diff --git a/.metadata/.log b/.metadata/.log deleted file mode 100644 index 93d3e86a61..0000000000 --- a/.metadata/.log +++ /dev/null @@ -1,253 +0,0 @@ - -!ENTRY org.eclipse.core.resources 4 2 2014-10-16 20:42:46.953 -!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.core.resources". -!STACK 0 -java.lang.IllegalStateException: Registry Directory not available: /Users/Elena/tutorials/.metadata/.plugins/org.eclipse.pde.core/.p2/org.eclipse.equinox.p2.engine/profileRegistry. - at org.eclipse.equinox.internal.p2.engine.SimpleProfileRegistry.restore(SimpleProfileRegistry.java:480) - at org.eclipse.equinox.internal.p2.engine.SimpleProfileRegistry.getProfileMap(SimpleProfileRegistry.java:338) - at org.eclipse.equinox.internal.p2.engine.SimpleProfileRegistry.getProfiles(SimpleProfileRegistry.java:320) - at org.eclipse.pde.internal.core.target.P2TargetUtils.cleanOrphanedTargetDefinitionProfiles(P2TargetUtils.java:168) - at org.eclipse.pde.internal.core.PDECore$1.saving(PDECore.java:274) - at org.eclipse.core.internal.resources.SaveManager.executeLifecycle(SaveManager.java:383) - at org.eclipse.core.internal.resources.SaveManager$1.run(SaveManager.java:192) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.core.internal.resources.SaveManager.broadcastLifecycle(SaveManager.java:195) - at org.eclipse.core.internal.resources.SaveManager.save(SaveManager.java:1130) - at org.eclipse.core.internal.resources.Workspace.save(Workspace.java:2376) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$5.run(IDEWorkbenchAdvisor.java:508) - at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121) - -!ENTRY org.eclipse.ui.ide 4 4 2014-10-16 20:42:55.472 -!MESSAGE Problems saving workspace - -!ENTRY org.eclipse.ui.ide 4 1 2014-10-16 20:42:55.472 -!MESSAGE Problems occurred while trying to save the state of the workbench. -!SUBENTRY 1 org.eclipse.core.resources 4 568 2014-10-16 20:42:55.472 -!MESSAGE Could not write workspace metadata '/Users/Elena/tutorials/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree'. -!STACK 0 -java.io.FileNotFoundException: /Users/Elena/tutorials/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree (No such file or directory) - at java.io.FileOutputStream.open(Native Method) - at java.io.FileOutputStream.(FileOutputStream.java:213) - at java.io.FileOutputStream.(FileOutputStream.java:162) - at org.eclipse.core.internal.localstore.SafeFileOutputStream.(SafeFileOutputStream.java:51) - at org.eclipse.core.internal.resources.SaveManager.saveTree(SaveManager.java:1352) - at org.eclipse.core.internal.resources.SaveManager.save(SaveManager.java:1134) - at org.eclipse.core.internal.resources.Workspace.save(Workspace.java:2376) - at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$5.run(IDEWorkbenchAdvisor.java:508) - at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121) -!SESSION 2014-10-16 20:43:17.092 ----------------------------------------------- -eclipse.buildId=4.3.2.M20140221-1700 -java.version=1.8.0_20 -java.vendor=Oracle Corporation -BootLoader constants: OS=macosx, ARCH=x86_64, WS=cocoa, NL=es_ES -Framework arguments: -product org.eclipse.epp.package.standard.product -keyring /Users/Elena/.eclipse_keyring -showlocation -Command-line arguments: -os macosx -ws cocoa -arch x86_64 -product org.eclipse.epp.package.standard.product -keyring /Users/Elena/.eclipse_keyring -showlocation - -!ENTRY org.eclipse.core.net 1 0 2014-10-16 20:43:52.743 -!MESSAGE System property http.nonProxyHosts has been set to local|*.local|169.254/16|*.169.254/16 by an external source. This value will be overwritten using the values from the preferences - -!ENTRY org.eclipse.jface 2 0 2014-10-16 20:43:53.942 -!MESSAGE Keybinding conflicts occurred. They may interfere with normal accelerator operation. -!SUBENTRY 1 org.eclipse.jface 2 0 2014-10-16 20:43:53.943 -!MESSAGE A conflict occurred for COMMAND+SHIFT+F10: -Binding(COMMAND+SHIFT+F10, - ParameterizedCommand(Command(org.jboss.tools.common.ui.RegisterAsService,Register As Service, - Adds class name to META-INF/services/%serviceType% file after service type is selected in the dialog from types extended and implemented by the class., - Category(org.eclipse.ui.category.file,File,null,true), - org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@2df3545d, - ,,true),null), - org.eclipse.ui.defaultAcceleratorConfiguration, - org.eclipse.ui.contexts.window,,,system) -Binding(COMMAND+SHIFT+F10, - ParameterizedCommand(Command(org.eclipse.ui.window.showSystemMenu,Show System Menu, - Show the system menu, - Category(org.eclipse.ui.category.window,Window,null,true), - org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@75ad30c1, - ,,true),null), - org.eclipse.ui.defaultAcceleratorConfiguration, - org.eclipse.ui.contexts.window,,cocoa,system) -!SUBENTRY 1 org.eclipse.jface 2 0 2014-10-16 20:43:53.943 -!MESSAGE A conflict occurred for ALT+COMMAND+Z: -Binding(ALT+COMMAND+Z, - ParameterizedCommand(Command(org.jboss.tools.cdi.ui.open.namedBean,Open CDI Named Bean, - Open CDI Named Bean, - Category(org.eclipse.ui.category.navigate,Navigate,null,true), - org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@fe8aaeb, - ,,true),null), - org.eclipse.ui.defaultAcceleratorConfiguration, - org.eclipse.ui.contexts.window,,,system) -Binding(ALT+COMMAND+Z, - ParameterizedCommand(Command(org.eclipse.jdt.ui.edit.text.java.surround.with.quickMenu,Surround With Quick Menu, - Shows the Surround With quick menu, - Category(org.eclipse.jdt.ui.category.source,Source,Java Source Actions,true), - org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@6b9697ae, - ,,true),null), - org.eclipse.ui.defaultAcceleratorConfiguration, - org.eclipse.ui.contexts.window,,cocoa,system) - -!ENTRY com.android.ide.eclipse.adt 1 0 2014-10-16 20:44:03.016 -!MESSAGE No valid Android XML Editor Delegate found for file /handling-spring-static-resources/pom.xml [Res null, type null] - -!ENTRY org.eclipse.e4.ui.workbench 4 0 2014-10-16 20:44:06.875 -!MESSAGE -!STACK 0 -org.eclipse.core.runtime.AssertionFailedException: assertion failed: - at org.eclipse.core.runtime.Assert.isTrue(Assert.java:110) - at org.eclipse.core.runtime.Assert.isTrue(Assert.java:96) - at org.eclipse.ui.part.MultiPageEditorPart.setActivePage(MultiPageEditorPart.java:1081) - at org.eclipse.ui.forms.editor.FormEditor.setActivePage(FormEditor.java:607) - at org.eclipse.ui.part.MultiPageEditorPart.createPartControl(MultiPageEditorPart.java:362) - at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.createPartControl(CompatibilityPart.java:142) - at org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor.createPartControl(CompatibilityEditor.java:96) - at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.create(CompatibilityPart.java:323) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:483) - at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:56) - at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:877) - at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:857) - at org.eclipse.e4.core.internal.di.InjectorImpl.inject(InjectorImpl.java:119) - at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:333) - at org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:254) - at org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:162) - at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.createFromBundle(ReflectionContributionFactory.java:102) - at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.doCreate(ReflectionContributionFactory.java:71) - at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.create(ReflectionContributionFactory.java:53) - at org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer.createWidget(ContributedPartRenderer.java:129) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:949) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:633) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:735) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:706) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:700) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:685) - at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer.showTab(StackRenderer.java:1147) - at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.postProcess(LazyStackRenderer.java:96) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:649) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:735) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:706) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:700) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:685) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:62) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:645) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$6.run(PartRenderingEngine.java:526) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:511) - at org.eclipse.e4.ui.workbench.renderers.swt.ElementReferenceRenderer.createWidget(ElementReferenceRenderer.java:61) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:949) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:633) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:735) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:706) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:700) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:685) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:62) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:645) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:735) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:706) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:700) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:685) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:62) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:645) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:735) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:706) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:700) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:685) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:62) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:645) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:735) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:706) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:700) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:685) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:62) - at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveRenderer.processContents(PerspectiveRenderer.java:59) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:645) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:735) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:706) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:700) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:685) - at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.showTab(PerspectiveStackRenderer.java:103) - at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.postProcess(LazyStackRenderer.java:96) - at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.postProcess(PerspectiveStackRenderer.java:77) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:649) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:735) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:706) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:700) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:685) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:62) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:645) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:735) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:706) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:700) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:685) - at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:62) - at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer.processContents(WBWRenderer.java:581) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:645) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:735) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:706) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:700) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:685) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1042) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) - at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:997) - at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:140) - at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:611) - at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) - at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:567) - at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150) - at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124) - at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) - at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354) - at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181) - at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) - at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) - at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) - at java.lang.reflect.Method.invoke(Method.java:483) - at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636) - at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591) - at org.eclipse.equinox.launcher.Main.run(Main.java:1450) - -!ENTRY org.eclipse.mylyn.tasks.ui 4 0 2014-10-16 20:44:08.029 -!MESSAGE Could not load repository template extension contributed by org.eclipse.mylyn.bugzilla.ide with connectorKind bugzilla - -!ENTRY org.eclipse.mylyn.tasks.ui 4 0 2014-10-16 20:44:08.029 -!MESSAGE Could not load repository template extension contributed by org.springsource.ide.eclipse.dashboard.ui with connectorKind jira - -!ENTRY org.eclipse.mylyn.tasks.ui 4 0 2014-10-16 20:44:08.030 -!MESSAGE Could not load repository template extension contributed by org.springsource.ide.eclipse.dashboard.ui with connectorKind jira - -!ENTRY org.eclipse.ui.workbench 4 2 2014-10-16 20:44:30.651 -!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.ui.workbench". -!STACK 0 -java.lang.NullPointerException - at org.springframework.ide.eclipse.maven.internal.legacyconversion.LegacyProjectChecker.earlyStartup(LegacyProjectChecker.java:36) - at org.eclipse.ui.internal.EarlyStartupRunnable.runEarlyStartup(EarlyStartupRunnable.java:87) - at org.eclipse.ui.internal.EarlyStartupRunnable.run(EarlyStartupRunnable.java:66) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.ui.internal.Workbench$55.run(Workbench.java:2555) - at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53) - -!ENTRY org.eclipse.ui 4 4 2014-10-16 20:44:30.663 -!MESSAGE Unhandled Exception - -!ENTRY org.springframework.ide.eclipse.maven 4 0 2014-10-16 20:44:30.663 -!MESSAGE Unable to execute early startup code for an extension -!STACK 0 -java.lang.NullPointerException - at org.springframework.ide.eclipse.maven.internal.legacyconversion.LegacyProjectChecker.earlyStartup(LegacyProjectChecker.java:36) - at org.eclipse.ui.internal.EarlyStartupRunnable.runEarlyStartup(EarlyStartupRunnable.java:87) - at org.eclipse.ui.internal.EarlyStartupRunnable.run(EarlyStartupRunnable.java:66) - at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) - at org.eclipse.ui.internal.Workbench$55.run(Workbench.java:2555) - at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53) diff --git a/.metadata/.mylyn/.taskListIndex/segments.gen b/.metadata/.mylyn/.taskListIndex/segments.gen deleted file mode 100644 index 63a7ec9a3c..0000000000 Binary files a/.metadata/.mylyn/.taskListIndex/segments.gen and /dev/null differ diff --git a/.metadata/.mylyn/.taskListIndex/segments_1 b/.metadata/.mylyn/.taskListIndex/segments_1 deleted file mode 100644 index 6b350b10f4..0000000000 Binary files a/.metadata/.mylyn/.taskListIndex/segments_1 and /dev/null differ diff --git a/.metadata/.mylyn/repositories.xml.zip b/.metadata/.mylyn/repositories.xml.zip deleted file mode 100644 index 0f05d185fc..0000000000 Binary files a/.metadata/.mylyn/repositories.xml.zip and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.markers.snap b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.markers.snap deleted file mode 100644 index 91d6c54151..0000000000 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.markers.snap and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.syncinfo.snap b/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.syncinfo.snap deleted file mode 100644 index 91d6c54151..0000000000 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.projects/RemoteSystemsTempFiles/.syncinfo.snap and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/handling-spring-static-resources/org.eclipse.jdt.core/state.dat b/.metadata/.plugins/org.eclipse.core.resources/.projects/handling-spring-static-resources/org.eclipse.jdt.core/state.dat deleted file mode 100644 index 1b30d3ec25..0000000000 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.projects/handling-spring-static-resources/org.eclipse.jdt.core/state.dat and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/handling-spring-static-resources/org.eclipse.wst.jsdt.core/state.dat b/.metadata/.plugins/org.eclipse.core.resources/.projects/handling-spring-static-resources/org.eclipse.wst.jsdt.core/state.dat deleted file mode 100644 index ec85483841..0000000000 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.projects/handling-spring-static-resources/org.eclipse.wst.jsdt.core/state.dat and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version deleted file mode 100644 index 25cb955ba2..0000000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index deleted file mode 100644 index 3931c81cf2..0000000000 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version deleted file mode 100644 index 6b2aaa7640..0000000000 --- a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap b/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap deleted file mode 100644 index 91d6c54151..0000000000 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree b/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree deleted file mode 100644 index 693f619ff9..0000000000 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources deleted file mode 100644 index 4d3c581705..0000000000 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.snap b/.metadata/.plugins/org.eclipse.core.resources/.snap deleted file mode 100644 index 156857881f..0000000000 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.snap and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi deleted file mode 100644 index 6c1bf27179..0000000000 --- a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi +++ /dev/null @@ -1,3889 +0,0 @@ - - - - activeSchemeId:org.eclipse.ui.defaultAcceleratorConfiguration - ModelMigrationProcessor.001 - - - - - - topLevel - - - Minimized - MinimizedByZoom - - - persp.actionSet:ajrefactoring - persp.actionSet:org.eclipse.contribution.xref.ui.XRefActionSet - persp.actionSet:org.eclipse.mylyn.context.ui.actionSet - persp.actionSet:org.eclipse.mylyn.doc.actionSet - persp.actionSet:org.eclipse.mylyn.tasks.ui.navigation - persp.actionSet:org.eclipse.ui.cheatsheets.actionSet - persp.actionSet:org.eclipse.rse.core.search.searchActionSet - persp.actionSet:org.eclipse.search.searchActionSet - persp.actionSet:org.eclipse.ui.edit.text.actionSet.annotationNavigation - persp.actionSet:org.eclipse.ui.edit.text.actionSet.navigation - persp.actionSet:org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo - persp.actionSet:org.eclipse.ui.externaltools.ExternalToolsSet - persp.actionSet:org.eclipse.ui.actionSet.keyBindings - persp.actionSet:org.eclipse.ui.actionSet.openFiles - persp.actionSet:org.jboss.ide.eclipse.archives.ui.actions.Archives - persp.actionSet:org.jboss.tools.jst.web.ui.server.actionSet - persp.actionSet:org.jboss.tools.central - persp.actionSet:org.jboss.tools.common.model.ui.actionSet - persp.actionSet:org.springframework.ide.eclipse.aop.ui.ActionSet - persp.actionSet:org.springframework.ide.eclipse.aop.ui.matcher.actionSet - persp.actionSet:org.springframework.ide.eclipse.beans.ui.actionSet - persp.actionSet:org.springframework.ide.eclipse.beans.search.actionSet - persp.actionSet:org.springsource.ide.eclipse.quicksearch.actionSet - persp.actionSet:org.springsource.ide.eclipse.commons.launch.actionSet - persp.actionSet:com.springsource.sts.ide.ui.actionSet.workbench - persp.actionSet:org.eclipse.debug.ui.launchActionSet - persp.actionSet:org.eclipse.jdt.ui.JavaActionSet - persp.actionSet:org.eclipse.jdt.ui.JavaElementCreationActionSet - persp.actionSet:org.eclipse.ui.NavigateActionSet - persp.viewSC:org.eclipse.jdt.ui.PackageExplorer - persp.viewSC:org.eclipse.jdt.ui.TypeHierarchy - persp.viewSC:org.eclipse.jdt.ui.SourceView - persp.viewSC:org.eclipse.jdt.ui.JavadocView - persp.viewSC:org.eclipse.search.ui.views.SearchView - persp.viewSC:org.eclipse.ui.console.ConsoleView - persp.viewSC:org.eclipse.ui.views.ContentOutline - persp.viewSC:org.eclipse.ui.views.ProblemView - persp.viewSC:org.eclipse.ui.views.ResourceNavigator - persp.viewSC:org.eclipse.ui.views.TaskList - persp.viewSC:org.eclipse.ui.views.ProgressView - persp.viewSC:org.eclipse.ui.navigator.ProjectExplorer - persp.viewSC:org.eclipse.ui.texteditor.TemplatesView - persp.viewSC:org.eclipse.pde.runtime.LogView - persp.newWizSC:org.eclipse.jdt.ui.wizards.JavaProjectWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewPackageCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewClassCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewEnumCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewAnnotationCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewSourceFolderCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewSnippetFileCreationWizard - persp.newWizSC:org.eclipse.jdt.ui.wizards.NewJavaWorkingSetWizard - persp.newWizSC:org.eclipse.ui.wizards.new.folder - persp.newWizSC:org.eclipse.ui.wizards.new.file - persp.newWizSC:org.eclipse.ui.editors.wizards.UntitledTextFileWizard - persp.perspSC:org.eclipse.jdt.ui.JavaBrowsingPerspective - persp.perspSC:org.eclipse.debug.ui.DebugPerspective - persp.newWizSC:com.android.ide.eclipse.adt.project.NewProjectWizard - persp.newWizSC:com.android.ide.eclipse.editors.wizards.NewXmlFileWizard - persp.actionSet:adt.actionSet.wizards - persp.actionSet:adt.actionSet.avdManager - persp.actionSet:adt.actionSet.lint - persp.actionSet:adt.actionSet.refactorings - persp.perspSC:com.android.ide.eclipse.ddms.Perspective - persp.perspSC:com.android.ide.eclipse.hierarchyviewer.PixelPerfectPespective - persp.perspSC:com.android.ide.eclipse.hierarchyviewer.TreeViewPerspective - persp.actionSet:ajelementCreation - persp.newWizSC:ajaspectwizard - persp.newWizSC:ajprojectwizard - persp.perspSC:org.eclipse.ajdt.ui.visualiser.AspectVisualizationPerspective - persp.viewSC:org.eclipse.ant.ui.views.AntView - persp.perspSC:org.eclipse.birt.report.designer.ui.ReportPerspective - persp.newWizSC:org.eclipse.birt.report.designer.ui.ide.wizards.NewReportWizard - persp.newWizSC:org.eclipse.birt.report.designer.ui.ide.wizards.NewTemplateWizard - persp.newWizSC:org.eclipse.birt.report.designer.ui.wizards.NewLibraryWizard - persp.showIn:org.eclipse.egit.ui.RepositoriesView - persp.actionSet:org.eclipse.debug.ui.breakpointActionSet - persp.actionSet:org.eclipse.jdt.debug.ui.JDTDebugActionSet - persp.newWizSC:org.eclipse.jdt.junit.wizards.NewTestCaseCreationWizard - persp.actionSet:org.eclipse.jdt.junit.JUnitActionSet - persp.showIn:org.eclipse.jdt.ui.PackageExplorer - persp.showIn:org.eclipse.team.ui.GenericHistoryView - persp.showIn:org.eclipse.ui.views.ResourceNavigator - persp.showIn:org.eclipse.ui.navigator.ProjectExplorer - persp.viewSC:org.eclipse.mylyn.tasks.ui.views.tasks - persp.newWizSC:org.eclipse.mylyn.tasks.ui.wizards.new.repository.task - persp.perspSC:org.eclipse.wst.jsdt.ui.JavaPerspective - persp.actionSet:org.hibernate.eclipse.launch.actionset - persp.showIn:org.jboss.tools.forge.ui.view - persp.perspSC:org.jboss.tools.jst.web.ui.WebDevelopmentPerspective - persp.viewSC:org.jboss.tools.common.model.ui.navigator.NavigatorViewPart - persp.viewSC:org.springframework.ide.eclipse.aop.ui.navigator.aopReferenceModelNavigator - persp.viewSC:org.springframework.ide.eclipse.aop.ui.tracing.eventTraceView - persp.newWizSC:org.springframework.ide.eclipse.beans.ui.wizards.newBeansConfig - persp.newWizSC:org.eclipse.m2e.core.wizards.Maven2ProjectWizard - persp.newWizSC:com.springsource.sts.roo.ui.wizard.newRooProjectWizard - persp.showIn:org.springframework.ide.eclipse.ui.navigator.springExplorer - persp.viewSC:org.springframework.ide.eclipse.ui.navigator.springExplorer - persp.newWizSC:org.springframework.ide.eclipse.webflow.ui.wizard.newWebflowConfigWizard - persp.newWizSC:com.springsource.sts.wizard.template - persp.newWizSC:org.springsource.ide.eclipse.commons.gettingstarted.wizard.boot.NewSpringBootWizard - persp.newWizSC:org.springsource.ide.eclipse.gettingstarted.wizards.import.generic.newalias - - - - newtablook - org.eclipse.e4.primaryNavigationStack - - - - - - - - newtablook - - - - - - - - - - newtablook - - - - - - newtablook - org.eclipse.e4.secondaryNavigationStack - - - - - - newtablook - - - - - newtablook - - - - - - newtablook - - - - - - newtablook - org.eclipse.e4.secondaryDataStack - - - - - - - - - - - - - - - - active - Maximized - - - - - - - View - categoryTag:Help - - - View - categoryTag:General - active - - ViewMenu - menuContribution:menu - - - - - View - categoryTag:Help - - - - newtablook - org.eclipse.e4.primaryDataStack - EditorStack - - - Editor - org.eclipse.wst.server.ui.editor - removeOnHide - - - - Editor - com.android.ide.eclipse.editors.CommonXmlEditor - removeOnHide - - - - Editor - com.android.ide.eclipse.editors.CommonXmlEditor - removeOnHide - - - - Editor - com.android.ide.eclipse.editors.CommonXmlEditor - removeOnHide - - - - Editor - com.android.ide.eclipse.editors.CommonXmlEditor - removeOnHide - - - - Editor - com.android.ide.eclipse.editors.CommonXmlEditor - removeOnHide - - - - Editor - com.android.ide.eclipse.editors.CommonXmlEditor - removeOnHide - - - - - - View - categoryTag:Java - - ViewMenu - menuContribution:menu - - - - - View - categoryTag:Java - - - View - categoryTag:General - - - View - categoryTag:General - - - - View - categoryTag:General - - ViewMenu - menuContribution:menu - - - - - View - categoryTag:Java - - - - View - categoryTag:Java - - ViewMenu - menuContribution:menu - - - - - - View - categoryTag:General - - ViewMenu - menuContribution:menu - - - - - - View - categoryTag:General - - ViewMenu - menuContribution:menu - - - - - View - categoryTag:General - - - View - categoryTag:General - - - - View - categoryTag:General - - ViewMenu - menuContribution:menu - - - - - View - categoryTag:General - - - View - categoryTag:Ant - - - View - categoryTag:AspectJ - - - View - categoryTag:Git - - - View - categoryTag:Java - - - - View - categoryTag:Mylyn - - ViewMenu - menuContribution:menu - - - - - View - categoryTag:Spring - - - - View - categoryTag:Spring - - ViewMenu - menuContribution:menu - - - - - - View - categoryTag:Server - - ViewMenu - menuContribution:menu - - - - - - View - categoryTag:General - - ViewMenu - menuContribution:menu - - - - - - toolbarSeparator - - - - Draggable - - - - - - - - - - - - - - - toolbarSeparator - - - - Draggable - - - - - - Draggable - - - - - Draggable - - - - - Draggable - - - - - Draggable - - - - - - - - - - - Draggable - - - - - - - - Draggable - - - - - - - - Draggable - - - - - - - Draggable - - - - - - - - - - toolbarSeparator - - - - Draggable - - - - - - - - - - - - toolbarSeparator - - - - toolbarSeparator - - - - Draggable - - - - - - stretch - - - glue - - - - glue - - - Draggable - - - - - stretch - - - - Draggable - - - - - - TrimStack - - - - - - - - - - - - - platform:cocoa - - - - - - - - - - platform:cocoa - - - - - - - - - - - - - platform:cocoa - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - platform:cocoa - - - - - platform:cocoa - - - - - platform:cocoa - - - - - platform:cocoa - - - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - - - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - - - - - - - - platform:cocoa - - - - - - - - - - - - platform:cocoa - - - - - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - platform:cocoa - - - platform:cocoa - - - - platform:cocoa - - - platform:cocoa - - - - - - - platform:cocoa - - - platform:cocoa - - - - platform:cocoa - - - - - - - - - - - - - - - - - - - - - - - platform:cocoa - - - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - - - - platform:cocoa - - - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - - - platform:cocoa - - - - - - - - - - platform:cocoa - - - - - platform:cocoa - - - - platform:cocoa - - - - - - - - - - - - platform:cocoa - - - - - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - - platform:cocoa - - - - - - - - - - - platform:cocoa - - - platform:cocoa - - - - platform:cocoa - - - - - - platform:cocoa - - - - - - - - - platform:cocoa - - - - - - - platform:cocoa - - - - platform:cocoa - - - - - - - - - - platform:cocoa - - - - - platform:cocoa - - - platform:cocoa - - - - platform:cocoa - - - platform:cocoa - - - - - - - - - - - - platform:cocoa - - - - platform:cocoa - - - - platform:cocoa - - - - platform:cocoa - - - - platform:cocoa - - - - platform:cocoa - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - platform:cocoa - - - - - - platform:cocoa - - - platform:cocoa - - - - platform:cocoa - - - - platform:cocoa - - - platform:cocoa - - - - platform:cocoa - - - platform:cocoa - - - - platform:cocoa - - - - platform:cocoa - - - - platform:cocoa - - - - platform:cocoa - - - - platform:cocoa - - - platform:cocoa - - - - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - - - - platform:cocoa - - - - - platform:cocoa - - - - - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - - - - - - platform:cocoa - - - - - platform:cocoa - - - - platform:cocoa - - - - - - - platform:cocoa - - - platform:cocoa - - - - - - - - - - - - - platform:cocoa - - - platform:cocoa - - - - - - - - - - - - - - - - - platform:cocoa - - - platform:cocoa - - - - - platform:cocoa - - - - platform:cocoa - - - - - - platform:cocoa - - - - platform:cocoa - - - - - - platform:cocoa - - - - - platform:cocoa - - - platform:cocoa - - - - - - - - platform:cocoa - - - - - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - - - - - - - - - - - - platform:cocoa - - - - - - - platform:cocoa - - - - - - - - platform:cocoa - - - - - platform:cocoa - - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - - platform:cocoa - - - - - platform:cocoa - - - - - platform:cocoa - - - - - platform:cocoa - - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - platform:cocoa - - - - - platform:cocoa - - - - - - - - platform:cocoa - - - - - - - - - - - - - - - - - - - - - - - - - - platform:cocoa - - - - - - - - - platform:cocoa - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - platform:cocoa - - - - platform:cocoa - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Editor - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Tracer for OpenGL ES - - - View - categoryTag:Tracer for OpenGL ES - - - View - categoryTag:Tracer for OpenGL ES - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:Android - - - View - categoryTag:AspectJ - - - View - categoryTag:Ant - - - View - categoryTag:Report Design - - - View - categoryTag:Report Design - - - View - categoryTag:Report Design - - - View - categoryTag:&C/C++ - - - View - categoryTag:Debug - - - View - categoryTag:Debug - - - View - categoryTag:Debug - - - View - categoryTag:Debug - - - View - categoryTag:Debug - - - View - categoryTag:Make - - - View - categoryTag:&C/C++ - - - View - categoryTag:&C/C++ - - - View - categoryTag:&C/C++ - - - View - categoryTag:&C/C++ - - - View - categoryTag:&C/C++ - - - View - categoryTag:General - - - View - categoryTag:Visualiser - - - View - categoryTag:Visualiser - - - View - categoryTag:AspectJ - - - View - categoryTag:Data Management - - - View - categoryTag:Data Management - - - View - categoryTag:Data Management - - - View - categoryTag:Debug - - - View - categoryTag:Debug - - - View - categoryTag:Debug - - - View - categoryTag:Debug - - - View - categoryTag:Debug - - - View - categoryTag:Debug - - - View - categoryTag:Debug - - - View - categoryTag:Git - - - View - categoryTag:Git - - - View - categoryTag:Git - - - View - categoryTag:Git - - - View - categoryTag:Git - - - View - categoryTag:General - - - View - categoryTag:Help - - - View - categoryTag:JPA - - - View - categoryTag:JPA - - - View - categoryTag:JavaServer Faces - - - View - categoryTag:JavaServer Faces - - - View - categoryTag:Maven - - - View - categoryTag:Maven - - - View - categoryTag:Mylyn - - - View - categoryTag:Mylyn - - - View - categoryTag:Mylyn - - - View - categoryTag:API Tools - - - View - categoryTag:Plug-in Development - - - View - categoryTag:Plug-in Development - - - View - categoryTag:Plug-in Development - - - View - categoryTag:Plug-in Development - - - View - categoryTag:Plug-in Development - - - View - categoryTag:Remote Systems - - - View - categoryTag:Remote Systems - - - View - categoryTag:Remote Systems - - - View - categoryTag:Remote Systems - - - View - categoryTag:Remote Systems - - - View - categoryTag:Remote Systems - - - View - categoryTag:Remote Systems - - - View - categoryTag:Remote Systems - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:CVS - - - View - categoryTag:CVS - - - View - categoryTag:Team - - - View - categoryTag:Team - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:Help - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:General - - - View - categoryTag:Debug - - - View - categoryTag:JavaScript - - - View - categoryTag:JavaScript - - - View - categoryTag:JavaScript - - - View - categoryTag:JavaScript - - - View - categoryTag:JavaScript - - - View - categoryTag:Server - - - View - categoryTag:XML - - - View - categoryTag:XML - - - View - categoryTag:Hibernate - - - View - categoryTag:Hibernate - - - View - categoryTag:Hibernate - - - View - categoryTag:Hibernate - - - View - categoryTag:JBoss Tools - - - View - categoryTag:Server - - - View - categoryTag:Forge - - - View - categoryTag:JMX - - - View - categoryTag:JBoss Tools Web - - - View - categoryTag:JBoss Tools Web - - - View - categoryTag:JBoss Tools Web - - - View - categoryTag:JBoss Tools - - - View - categoryTag:Seam - - - View - categoryTag:JBoss Tools Web Services - - - View - categoryTag:Spring - - - View - categoryTag:Spring - - - View - categoryTag:Spring - - - View - categoryTag:Spring - - - View - categoryTag:Spring - - - View - categoryTag:Spring - - - View - categoryTag:Spring - - - View - categoryTag:Debug - - - View - categoryTag:Java - - - View - categoryTag:Java - - - View - categoryTag:Java - - - View - categoryTag:Java Browsing - - - View - categoryTag:Java Browsing - - - View - categoryTag:Java Browsing - - - View - categoryTag:Java Browsing - - - View - categoryTag:Java - - - View - categoryTag:Java - - - View - categoryTag:Java - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache b/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache deleted file mode 100644 index dd4af88111..0000000000 Binary files a/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps b/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps deleted file mode 100644 index 80b5f91d54..0000000000 Binary files a/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/indexNamesMap.txt b/.metadata/.plugins/org.eclipse.jdt.core/indexNamesMap.txt deleted file mode 100644 index 32e47edfaf..0000000000 --- a/.metadata/.plugins/org.eclipse.jdt.core/indexNamesMap.txt +++ /dev/null @@ -1 +0,0 @@ -INDEX VERSION 1.127 diff --git a/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache b/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache deleted file mode 100644 index 593f4708db..0000000000 Binary files a/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt b/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt deleted file mode 100644 index 4644f71d79..0000000000 --- a/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt +++ /dev/null @@ -1,2 +0,0 @@ -aj -java \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache deleted file mode 100644 index d3473153f2..0000000000 Binary files a/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt b/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt deleted file mode 100644 index 3af5ad5b80..0000000000 --- a/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt +++ /dev/null @@ -1,23 +0,0 @@ -INDEX VERSION 1.127+/Users/Elena/tutorials/.metadata/.plugins/org.eclipse.jdt.core -4249315662.index -1271342938.index -272178059.index -3712507179.index -2996324989.index -1833648217.index -3302703152.index -450555687.index -4238209716.index -3954040986.index -1819685514.index -770573466.index -156905802.index -3004609673.index -2545238116.index -2326659272.index -3266567714.index -1384487945.index -84777399.index -3000285004.index -765977872.index -3321539481.index diff --git a/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat deleted file mode 100644 index e91b239486..0000000000 Binary files a/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml b/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml deleted file mode 100644 index 81c4e135f3..0000000000 --- a/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml deleted file mode 100644 index a4ee3cbc9a..0000000000 --- a/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml deleted file mode 100644 index 9e390f501d..0000000000 --- a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml deleted file mode 100644 index a67b723f21..0000000000 --- a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml +++ /dev/null @@ -1,13 +0,0 @@ - -
-
- - - - - -
-
- -
-
diff --git a/.metadata/.plugins/org.eclipse.jst.jsp.core/taglibindex/2996324989.dat b/.metadata/.plugins/org.eclipse.jst.jsp.core/taglibindex/2996324989.dat deleted file mode 100644 index 9f3dde8c83..0000000000 Binary files a/.metadata/.plugins/org.eclipse.jst.jsp.core/taglibindex/2996324989.dat and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml deleted file mode 100644 index aa26784293..0000000000 --- a/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml +++ /dev/null @@ -1,7 +0,0 @@ - -
-
- - -
-
diff --git a/.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser b/.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser deleted file mode 100644 index a02fb4650f..0000000000 Binary files a/.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties b/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties deleted file mode 100644 index b8528c313e..0000000000 --- a/.metadata/.plugins/org.eclipse.pde.core/.cache/clean-cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Cached timestamps -#Thu Oct 16 20:42:58 PET 2014 diff --git a/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.macbook-pro-de-elena-garcia-miro-p_9697497121/FP.local.files_0/node.properties b/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.macbook-pro-de-elena-garcia-miro-p_9697497121/FP.local.files_0/node.properties deleted file mode 100644 index 1fd82a90dd..0000000000 --- a/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.macbook-pro-de-elena-garcia-miro-p_9697497121/FP.local.files_0/node.properties +++ /dev/null @@ -1,57 +0,0 @@ -# RSE DOM Node -00-name=MacBook-Pro-de-Elena-Garcia-Miro-P\:local.files -01-type=FilterPool -03-attr.default=true -03-attr.deletable=true -03-attr.id=local.files -03-attr.nonRenamable=false -03-attr.owningParentName=null -03-attr.release=200 -03-attr.singleFilterStringOnly=false -03-attr.singleFilterStringOnlyESet=false -03-attr.stringsCaseSensitive=true -03-attr.supportsDuplicateFilterStrings=false -03-attr.supportsNestedFilters=true -03-attr.type=default -06-child.00000.00-name=My Home -06-child.00000.01-type=Filter -06-child.00000.03-attr.default=false -06-child.00000.03-attr.filterType=default -06-child.00000.03-attr.id=My Home -06-child.00000.03-attr.nonChangable=false -06-child.00000.03-attr.nonDeletable=false -06-child.00000.03-attr.nonRenamable=false -06-child.00000.03-attr.promptable=false -06-child.00000.03-attr.relativeOrder=0 -06-child.00000.03-attr.release=200 -06-child.00000.03-attr.singleFilterStringOnly=false -06-child.00000.03-attr.stringsCaseSensitive=true -06-child.00000.03-attr.stringsNonChangable=false -06-child.00000.03-attr.supportsDuplicateFilterStrings=false -06-child.00000.03-attr.supportsNestedFilters=true -06-child.00000.06-child.00000.00-name=/Users/Elena/* -06-child.00000.06-child.00000.01-type=FilterString -06-child.00000.06-child.00000.03-attr.default=false -06-child.00000.06-child.00000.03-attr.string=/Users/Elena/* -06-child.00000.06-child.00000.03-attr.type=default -06-child.00001.00-name=Root -06-child.00001.01-type=Filter -06-child.00001.03-attr.default=false -06-child.00001.03-attr.filterType=default -06-child.00001.03-attr.id=Root -06-child.00001.03-attr.nonChangable=false -06-child.00001.03-attr.nonDeletable=false -06-child.00001.03-attr.nonRenamable=false -06-child.00001.03-attr.promptable=false -06-child.00001.03-attr.relativeOrder=0 -06-child.00001.03-attr.release=200 -06-child.00001.03-attr.singleFilterStringOnly=false -06-child.00001.03-attr.stringsCaseSensitive=true -06-child.00001.03-attr.stringsNonChangable=false -06-child.00001.03-attr.supportsDuplicateFilterStrings=false -06-child.00001.03-attr.supportsNestedFilters=true -06-child.00001.06-child.00000.00-name=/* -06-child.00001.06-child.00000.01-type=FilterString -06-child.00001.06-child.00000.03-attr.default=false -06-child.00001.06-child.00000.03-attr.string=/* -06-child.00001.06-child.00000.03-attr.type=default diff --git a/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.macbook-pro-de-elena-garcia-miro-p_9697497121/H.local_16/node.properties b/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.macbook-pro-de-elena-garcia-miro-p_9697497121/H.local_16/node.properties deleted file mode 100644 index 8adafb7810..0000000000 --- a/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.macbook-pro-de-elena-garcia-miro-p_9697497121/H.local_16/node.properties +++ /dev/null @@ -1,25 +0,0 @@ -# RSE DOM Node -00-name=Local -01-type=Host -03-attr.description= -03-attr.hostname=LOCALHOST -03-attr.offline=false -03-attr.promptable=false -03-attr.systemType=org.eclipse.rse.systemtype.local -03-attr.type=Local -06-child.00000.00-name=Local Connector Service -06-child.00000.01-type=ConnectorService -06-child.00000.03-attr.group=Local Connector Service -06-child.00000.03-attr.port=0 -06-child.00000.03-attr.useSSL=false -06-child.00000.06-child.00000.00-name=Local Files -06-child.00000.06-child.00000.01-type=SubSystem -06-child.00000.06-child.00000.03-attr.hidden=false -06-child.00000.06-child.00000.03-attr.type=local.files -06-child.00000.06-child.00000.06-child.00000.00-name=MacBook-Pro-de-Elena-Garcia-Miro-P___MacBook-Pro-de-Elena-Garcia-Miro-P\:local.files -06-child.00000.06-child.00000.06-child.00000.01-type=FilterPoolReference -06-child.00000.06-child.00000.06-child.00000.03-attr.refID=local.files -06-child.00000.06-child.00001.00-name=Local Shells -06-child.00000.06-child.00001.01-type=SubSystem -06-child.00000.06-child.00001.03-attr.hidden=false -06-child.00000.06-child.00001.03-attr.type=local.shells diff --git a/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.macbook-pro-de-elena-garcia-miro-p_9697497121/node.properties b/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.macbook-pro-de-elena-garcia-miro-p_9697497121/node.properties deleted file mode 100644 index ee267da8c7..0000000000 --- a/.metadata/.plugins/org.eclipse.rse.core/profiles/PRF.macbook-pro-de-elena-garcia-miro-p_9697497121/node.properties +++ /dev/null @@ -1,7 +0,0 @@ -# RSE DOM Node -00-name=MacBook-Pro-de-Elena-Garcia-Miro-P -01-type=Profile -03-attr.defaultPrivate=true -03-attr.isActive=true -05-ref.00000=FP.local.files_0 -05-ref.00001=H.local_16 diff --git a/.metadata/.plugins/org.eclipse.search/dialog_settings.xml b/.metadata/.plugins/org.eclipse.search/dialog_settings.xml deleted file mode 100644 index d2bdd1e49c..0000000000 --- a/.metadata/.plugins/org.eclipse.search/dialog_settings.xml +++ /dev/null @@ -1,70 +0,0 @@ - -
-
- -
-
- -
-
- - - - - -
- -
-
- - - - - - - - - - -
-
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
- - - - - -
-
diff --git a/.metadata/.plugins/org.eclipse.ui.editors/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.editors/dialog_settings.xml deleted file mode 100644 index 50f1edb316..0000000000 --- a/.metadata/.plugins/org.eclipse.ui.editors/dialog_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - -
-
-
-
diff --git a/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml deleted file mode 100644 index 24f718e1ca..0000000000 --- a/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml +++ /dev/null @@ -1,30 +0,0 @@ - -
-
- - - - - -
-
- - - - - - - - - - - -
- - - - - -
-
-
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench.texteditor/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.workbench.texteditor/dialog_settings.xml deleted file mode 100644 index b9f4ca805b..0000000000 --- a/.metadata/.plugins/org.eclipse.ui.workbench.texteditor/dialog_settings.xml +++ /dev/null @@ -1,23 +0,0 @@ - -
-
- - - - - - - - - - - -
-
- - - - - -
-
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml deleted file mode 100644 index 1ae420da85..0000000000 --- a/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml +++ /dev/null @@ -1,33 +0,0 @@ - -
-
- - - - - - - - - - -
-
- - - - -
-
- - - - - - - - - - -
-
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml deleted file mode 100644 index 61cd82aa2a..0000000000 --- a/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui/dialog_settings.xml deleted file mode 100644 index 5ca0b77690..0000000000 --- a/.metadata/.plugins/org.eclipse.ui/dialog_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - -
-
diff --git a/.metadata/.plugins/org.eclipse.wst.internet.cache/cache.xml b/.metadata/.plugins/org.eclipse.wst.internet.cache/cache.xml deleted file mode 100644 index 1b1be0f54e..0000000000 --- a/.metadata/.plugins/org.eclipse.wst.internet.cache/cache.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.wst.jsdt.core/externalLibsTimeStamps b/.metadata/.plugins/org.eclipse.wst.jsdt.core/externalLibsTimeStamps deleted file mode 100644 index 35109d64d3..0000000000 Binary files a/.metadata/.plugins/org.eclipse.wst.jsdt.core/externalLibsTimeStamps and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.wst.jsdt.core/variablesAndContainers.dat b/.metadata/.plugins/org.eclipse.wst.jsdt.core/variablesAndContainers.dat deleted file mode 100644 index ba9a8170ae..0000000000 Binary files a/.metadata/.plugins/org.eclipse.wst.jsdt.core/variablesAndContainers.dat and /dev/null differ diff --git a/.metadata/.plugins/org.eclipse.wst.jsdt.ui/OpenTypeHistory.xml b/.metadata/.plugins/org.eclipse.wst.jsdt.ui/OpenTypeHistory.xml deleted file mode 100644 index a4ee3cbc9a..0000000000 --- a/.metadata/.plugins/org.eclipse.wst.jsdt.ui/OpenTypeHistory.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/.metadata/.plugins/org.eclipse.wst.jsdt.ui/QualifiedTypeNameHistory.xml b/.metadata/.plugins/org.eclipse.wst.jsdt.ui/QualifiedTypeNameHistory.xml deleted file mode 100644 index 9e390f501d..0000000000 --- a/.metadata/.plugins/org.eclipse.wst.jsdt.ui/QualifiedTypeNameHistory.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/.metadata/.plugins/org.eclipse.wst.server.core/monitors.xml b/.metadata/.plugins/org.eclipse.wst.server.core/monitors.xml deleted file mode 100644 index 0bd2033fef..0000000000 --- a/.metadata/.plugins/org.eclipse.wst.server.core/monitors.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/.metadata/.plugins/org.eclipse.wst.sse.core/task-tags.properties b/.metadata/.plugins/org.eclipse.wst.sse.core/task-tags.properties deleted file mode 100644 index 4acf7ba3bc..0000000000 --- a/.metadata/.plugins/org.eclipse.wst.sse.core/task-tags.properties +++ /dev/null @@ -1,3 +0,0 @@ -# -#Thu Oct 16 20:44:26 PET 2014 -task-tag-projects-already-scanned= diff --git a/.metadata/.plugins/org.eclipse.wst.sse.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.wst.sse.ui/dialog_settings.xml deleted file mode 100644 index 63fae25e8f..0000000000 --- a/.metadata/.plugins/org.eclipse.wst.sse.ui/dialog_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - -
-
-
-
diff --git a/.metadata/.plugins/org.jboss.tools.central/dialog_settings.xml b/.metadata/.plugins/org.jboss.tools.central/dialog_settings.xml deleted file mode 100644 index f977cc958a..0000000000 --- a/.metadata/.plugins/org.jboss.tools.central/dialog_settings.xml +++ /dev/null @@ -1,8 +0,0 @@ - -
-
- - - -
-
diff --git a/.metadata/.plugins/org.springframework.ide.eclipse.aop.core/.state b/.metadata/.plugins/org.springframework.ide.eclipse.aop.core/.state deleted file mode 100644 index 8a7bbde21f..0000000000 --- a/.metadata/.plugins/org.springframework.ide.eclipse.aop.core/.state +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/.metadata/.plugins/org.springframework.ide.eclipse.beans.core.metadata/metadata/.state b/.metadata/.plugins/org.springframework.ide.eclipse.beans.core.metadata/metadata/.state deleted file mode 100644 index 9fa791da42..0000000000 Binary files a/.metadata/.plugins/org.springframework.ide.eclipse.beans.core.metadata/metadata/.state and /dev/null differ diff --git a/.metadata/.plugins/org.springframework.ide.eclipse.beans.core.metadata/properties/.state b/.metadata/.plugins/org.springframework.ide.eclipse.beans.core.metadata/properties/.state deleted file mode 100644 index 4e0dff42d9..0000000000 Binary files a/.metadata/.plugins/org.springframework.ide.eclipse.beans.core.metadata/properties/.state and /dev/null differ diff --git a/.metadata/.plugins/org.springsource.ide.eclipse.dashboard.ui/feeds/dashboard.feeds.blogs/-549550714.xml b/.metadata/.plugins/org.springsource.ide.eclipse.dashboard.ui/feeds/dashboard.feeds.blogs/-549550714.xml deleted file mode 100644 index ff2193fcc3..0000000000 --- a/.metadata/.plugins/org.springsource.ide.eclipse.dashboard.ui/feeds/dashboard.feeds.blogs/-549550714.xml +++ /dev/null @@ -1,816 +0,0 @@ - - - Spring - - - http://spring.io/blog.atom - https://spring.io/favicon.ico - 2014-10-15T13:20:00Z - - Whats new in Spring Data Evans? - - - - Christoph Strobl - - tag:spring.io,2014-09-17:1764 - 2014-10-15T13:20:00Z - <p>Spring Data Release <a href="https://spring.io/blog/2014/09/09/spring-data-release-train-evans-goes-ga">Evans</a> has been around for a while and it's more than time to finally introduce you to the latest and greatest features we shipped with it.</p> - -<p>There's a lot to cover since major enhancements have gone into the commons module. Those changes already have made it into some store modules and will go on and sneak their way into others over time, too. All of them are already available for at least <a href="http://projects.spring.io/spring-data-jpa/">Spring Data JPA</a>. That said, lets jump right in.</p> - -<h2> -<a name="user-content-advanced-support-for-java-8" class="anchor" href="#advanced-support-for-java-8" aria-hidden="true"><span class="octicon octicon-link"></span></a>Advanced support for Java 8</h2> - -<p>Java8 has now been around for a while and previous Spring Data release trains already added fundamental support for some of those. With the Evans release train we extended the support significantly.</p> - -<p>Java 8's <a href="http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html"><code>Optional</code></a> has been a supported return since the <a href="https://spring.io/blog/2014/05/21/what-s-new-in-spring-data-dijkstra">Dijkstra release</a> freeing you of having <code>null</code> checks spread across your code. We simply wrap and unwrap values for you when used as return types with repositories.</p> - -<p>As of the Evans release <a href="http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html">default methods</a> can be used in repository interfaces to e.g. forward parts of the parameters handed into the method to other query methods.</p> - -<div class="highlight highlight-java"><pre><span class="kd">interface</span> <span class="nc">PersonRepository</span> <span class="kd">extends</span> <span class="n">Repository</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span> <span class="o">{</span> - - <span class="n">Optional</span><span class="o">&lt;</span><span class="n">Customer</span><span class="o">&gt;</span> <span class="nf">findByLastname</span><span class="o">(</span><span class="n">String</span> <span class="n">lastname</span><span class="o">);</span> - - <span class="k">default</span> <span class="n">Optional</span><span class="o">&lt;</span><span class="n">Customer</span><span class="o">&gt;</span> <span class="nf">findByLastname</span><span class="o">(</span><span class="n">Customer</span> <span class="n">customer</span><span class="o">)</span> <span class="o">{</span> - <span class="k">return</span> <span class="nf">findByLastname</span><span class="o">(</span><span class="n">customer</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">?</span> <span class="kc">null</span> <span class="o">:</span> <span class="n">customer</span><span class="o">.</span><span class="na">getLastname</span><span class="o">());</span> - <span class="o">}</span> -<span class="o">}</span> -</pre></div> - -<h2> -<a name="user-content-enhanced-multi-store-support" class="anchor" href="#enhanced-multi-store-support" aria-hidden="true"><span class="octicon octicon-link"></span></a>Enhanced multi-store support</h2> - -<p>Configuring your application to make use of different Spring Data modules has not been without issues so far. E.g. you might want to combine JPA and MongoDB where <code>Customer</code> happens to be a JPA Entity while <code>Order</code> is a MongoDB Document both persisted via according repository interfaces.</p> - -<div class="highlight highlight-java"><pre><span class="nd">@Entity</span> -<span class="kd">class</span> <span class="nc">Customer</span> <span class="o">{</span> - - <span class="nd">@Id</span> <span class="nd">@GeneratedValue</span> <span class="n">Long</span> <span class="n">id</span><span class="o">;</span> - <span class="n">String</span> <span class="n">firstname</span><span class="o">,</span> <span class="n">lastname</span><span class="o">;</span> - <span class="c1">// ...</span> -<span class="o">}</span> - -<span class="nd">@Document</span> -<span class="kd">class</span> <span class="nc">Order</span> <span class="o">{</span> - - <span class="nd">@Id</span> <span class="n">String</span> <span class="n">id</span><span class="o">;</span> - <span class="n">Long</span> <span class="n">customerId</span><span class="o">;</span> - <span class="n">Date</span> <span class="n">orderDate</span><span class="o">;</span> - <span class="c1">// ...</span> -<span class="o">}</span> - -<span class="kd">interface</span> <span class="nc">CustomerRepository</span> <span class="kd">extends</span> <span class="n">CrudRepository</span><span class="o">&lt;</span><span class="n">Customer</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span> <span class="o">{}</span> - -<span class="kd">interface</span> <span class="nc">OrderRepository</span> <span class="kd">extends</span> <span class="n">CrudRepository</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">,</span> <span class="n">String</span><span class="o">&gt;</span> <span class="o">{}</span> -</pre></div> - -<p>Until the Spring Data Evans release you had to manually configure the repository setup for MongoDB and JPA to mutually exclude the interfaces not relevant for the given store. Users usually used separate packages for that.</p> - -<p>Now the repository setup detects that multiple Spring Data modules are on the classpath, and automatically restricts the repository scanning and inspect the domain type used by a given repository for store specific annotations such as <code>@Entity</code> and <code>@Document</code> to determine the concrete implementation they belong to. E.g. the Spring Data MongoDB module would drop the (accidentally) detected <code>CustomerRepository</code> as we don't find an <code>@Document</code> annotation.</p> - -<h3> -<a name="user-content-statically-limiting-results" class="anchor" href="#statically-limiting-results" aria-hidden="true"><span class="octicon octicon-link"></span></a>Statically limiting results</h3> - -<p>Dynamically limiting results is no new concept since Spring Data has had <code>Pagable</code> as abstraction since its inception and I bet nearly every Spring Data user is already familiar with something like this:</p> - -<div class="highlight highlight-java"><pre><span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="nf">findByLastname</span><span class="o">(</span><span class="n">String</span> <span class="n">lastname</span><span class="o">,</span> <span class="n">Pageable</span> <span class="n">page</span><span class="o">)</span> -</pre></div> - -<p>This method declaration provides quite some flexibility: clients define the page number, size and a sort order of the elements they want to access. This is great if these values change dynamically (e.g. when you traverse the result set page by page).</p> - -<p>But what if you're always only interested in e.g. the first 10 results and you always want them to be ordered by lastname? This could've been achieved by statically defining a <code>PageRequest</code> and reusing that for every method invocation. However, that still required the client to hand in the special <code>PageRequest</code>. </p> - -<p>As of Spring Data Evans we now offer you a convenient way to explicitly limit the result set to a certain number of elements by using the keywords <code>top</code> and <code>first</code> followed by an optional positive numeric value (defaulting to 1).</p> - -<div class="highlight highlight-java"><pre><span class="n">List</span><span class="o">&lt;</span><span class="n">Person</span><span class="o">&gt;</span> <span class="nf">findTop10ByLastnameOrderByFirstnameDesc</span><span class="o">(</span><span class="n">String</span> <span class="n">lastname</span><span class="o">);</span> -</pre></div> - -<h2> -<a name="user-content-mongodb-full-text-search" class="anchor" href="#mongodb-full-text-search" aria-hidden="true"><span class="octicon octicon-link"></span></a>MongoDB Full Text Search</h2> - -<p>The Evans RC1 release introduced basic <a href="https://spring.io/blog/2014/07/17/text-search-your-documents-with-spring-data-mongodb">text index support</a> for MongoDB 2.6. Using <code>@TextIndexed</code> allows you to mark properties you want to have text search enabled for so that we can go on and create the index for you. Note, that placing <code>@TextIndexed</code> on properties referring to complex types will index all properties of that type. Since scoring is a fundamental part of full text search the <code>@TextScore</code> annotation will assert that any full text query returns the documents score allowing you to order them by relevance.</p> - -<div class="highlight highlight-java"><pre><span class="nd">@Document</span> -<span class="kd">class</span> <span class="nc">BlogPost</span> <span class="o">{</span> - - <span class="nd">@Id</span> <span class="n">String</span> <span class="n">id</span><span class="o">;</span> - <span class="nd">@TextIndexed</span><span class="o">(</span><span class="n">weight</span> <span class="o">=</span> <span class="mi">3</span><span class="o">)</span> <span class="n">String</span> <span class="n">title</span><span class="o">;</span> - <span class="nd">@TextIndexed</span><span class="o">(</span><span class="n">weight</span> <span class="o">=</span> <span class="mi">2</span><span class="o">)</span> <span class="n">String</span> <span class="n">content</span><span class="o">;</span> - <span class="nd">@TextIndexed</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> <span class="n">categories</span><span class="o">;</span> - <span class="nd">@TextScore</span> <span class="n">Float</span> <span class="n">score</span><span class="o">;</span> -<span class="o">}</span> -</pre></div> - -<p>That in place, we extended the repository support to accept a <code>TextCriteria</code> instance that will define detailed options about the text search that shall be executed: the terms to be searched for, language options etc.</p> - -<div class="highlight highlight-java"><pre><span class="kd">interface</span> <span class="nc">BlogPostRepository</span> <span class="kd">extends</span> <span class="n">CrudRepository</span><span class="o">&lt;</span><span class="n">BlogPost</span><span class="o">,</span> <span class="n">String</span><span class="o">&gt;</span> <span class="o">{</span> - - <span class="n">Page</span><span class="o">&lt;</span><span class="n">BlogPost</span><span class="o">&gt;</span> <span class="nf">findBy</span><span class="o">(</span><span class="n">TextCriteria</span> <span class="n">criteria</span><span class="o">,</span> <span class="n">Pageable</span> <span class="n">page</span><span class="o">);</span> - - <span class="n">List</span><span class="o">&lt;</span><span class="n">BlogPost</span><span class="o">&gt;</span> <span class="nf">findAllByOrderByScoreDesc</span><span class="o">(</span><span class="n">TextCriteria</span> <span class="n">criteria</span><span class="o">);</span> -<span class="o">}</span> -</pre></div> - -<p>The first query method is quite straight forward. It executes the given <code>TextCriteria</code> and pages the results. The second query method definition combines the given <code>TextCriteria</code> with a standard criteria definition derived from the method name. This shows that you can freely combine text search with standard query easily.</p> - -<h2> -<a name="user-content-mongodb-query-modifiers" class="anchor" href="#mongodb-query-modifiers" aria-hidden="true"><span class="octicon octicon-link"></span></a>MongoDB query modifiers</h2> - -<p>We added <code>@Meta</code> allowing you to define output and behavior of a query. By setting e.g. <code>maxExecutionTime</code> one can define the maximum duration a query may take (in milliseconds). Any execution that exceeds the limit will result in an error. You can also advice MongoDB to only scan through a maximum number of documents and return what has been found until reaching the limit by setting <code>maxScanDocuments</code>, while <code>comment</code> allows you to define text you can search for within the <code>system.profile</code> collection in case you got profiling enabled for your MongoDB instance. </p> - -<div class="highlight highlight-java"><pre><span class="nd">@Meta</span><span class="o">(</span><span class="n">maxExcecutionTime</span> <span class="o">=</span> <span class="mi">100</span><span class="o">,</span> <span class="n">comment</span> <span class="o">=</span> <span class="s">"onlyLimitedTime"</span><span class="o">)</span> -<span class="n">List</span><span class="o">&lt;</span><span class="n">Customer</span><span class="o">&gt;</span> <span class="nf">findByFirstname</span><span class="o">(</span><span class="n">String</span> <span class="n">firstname</span><span class="o">);</span> -</pre></div> - -<h2> -<a name="user-content-configuration-options-for-redis-sentinel" class="anchor" href="#configuration-options-for-redis-sentinel" aria-hidden="true"><span class="octicon octicon-link"></span></a>Configuration options for Redis Sentinel</h2> - -<p>Redis 2.8 introduced high-availability support know as <a href="http://redis.io/topics/sentinel">Sentinels</a>. The Redis module of Spring Data Evans adds support to easily configure connecting to a sentinel setup so that your client will be able to continue working in case of re-elections of master nodes in a Redis cluster.</p> - -<p><code>RedisSentinelConfiguration</code> defines where the Sentiels are located so that the <code>ConnectionFactory</code> can set up pooling accordingly. In case of Jedis it will create a <code>JedisSentinelPool</code> for automatic failover. This means that in case your master node goes down, you'll receive, as soon as the Sentinels agreed on a new master, a connection to the new master without the need of any further interaction. </p> - -<div class="highlight highlight-java"><pre><span class="nd">@Configuration</span> -<span class="kd">class</span> <span class="nc">RedisSentinelApplicationConfig</span> <span class="o">{</span> - - <span class="nd">@Bean</span> - <span class="n">RedisConnectionFactory</span> <span class="nf">connectionFactory</span><span class="o">()</span> <span class="o">{</span> - <span class="k">return</span> <span class="k">new</span> <span class="nf">JedisConnectionFactory</span><span class="o">(</span><span class="n">sentinelConfig</span><span class="o">());</span> - <span class="o">}</span> - - <span class="nd">@Bean</span> - <span class="n">RedisSentinelConfiguration</span> <span class="nf">sentinelConfig</span><span class="o">()</span> <span class="o">{</span> - <span class="k">return</span> <span class="k">new</span> <span class="nf">RedisSentinelConfiguration</span><span class="o">().</span><span class="na">master</span><span class="o">(</span><span class="s">"mymaster"</span><span class="o">)</span> - <span class="o">.</span><span class="na">sentinel</span><span class="o">(</span><span class="s">"localhost"</span><span class="o">,</span> <span class="mi">26379</span><span class="o">)</span> - <span class="o">.</span><span class="na">sentinel</span><span class="o">(</span><span class="s">"localhost"</span><span class="o">,</span> <span class="mi">26380</span><span class="o">)</span> - <span class="o">.</span><span class="na">sentinel</span><span class="o">(</span><span class="s">"localhost"</span><span class="o">,</span> <span class="mi">26381</span><span class="o">);</span> - <span class="o">}</span> -<span class="o">}</span> -</pre></div> - -<p>The upcoming Spring Boot 1.2, will even take this even further by automatically picking up the <code>RedisSentinelConfiguration</code> if present and initialize the <code>RedisConnectionFactory</code> accordingly.</p> - -<h2> -<a name="user-content-schema-support-for-solr" class="anchor" href="#schema-support-for-solr" aria-hidden="true"><span class="octicon octicon-link"></span></a>Schema support for Solr</h2> - -<p>Although the <a href="https://cwiki.apache.org/confluence/display/solr/Schema+API">Solr Schema API</a> is not finished yet, we already try to support as much of it as possible. With the Evans release you can now dynamically add missing fields to an existing (managed) schema. To achieve this, we read the existing field definition and compare it against the one derived from the properties of the domain type. To do so we extended the <code>@Indexed</code> annotation a bit. It now allows some fine tuning of the fields to be created as values such as <code>indexed</code>, <code>stored</code> and <code>solrType</code> can be explicitly defined.</p> - -<div class="highlight highlight-java"><pre><span class="nd">@Configuration</span> -<span class="nd">@EnableSolrRepositories</span><span class="o">(</span><span class="n">schemaCreationSupport</span> <span class="o">=</span> <span class="kc">true</span><span class="o">)</span> -<span class="kd">class</span> <span class="nc">SolrConfiguration</span> <span class="o">{</span> - - <span class="nd">@Bean</span> - <span class="n">SolrServer</span> <span class="nf">solrServer</span><span class="o">()</span> <span class="o">{</span> - <span class="k">return</span> <span class="k">new</span> <span class="nf">HttpSolrServer</span><span class="o">(</span><span class="s">"http://localhost:8983/solr"</span><span class="o">);</span> - <span class="o">}</span> -<span class="o">}</span> - -<span class="nd">@SolrDocument</span><span class="o">(</span><span class="n">solrCoreName</span> <span class="o">=</span> <span class="s">"collection1"</span><span class="o">)</span> -<span class="kd">class</span> <span class="nc">ManagedProduct</span> <span class="o">{</span> - - <span class="nd">@Id</span> <span class="n">String</span> <span class="n">id</span><span class="o">;</span> - <span class="nd">@Indexed</span><span class="o">(</span><span class="n">type</span> <span class="o">=</span> <span class="s">"text_general"</span><span class="o">)</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span> - <span class="nd">@Indexed</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"cat"</span><span class="o">)</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> <span class="n">category</span><span class="o">;</span> -<span class="o">}</span> -</pre></div> - -<p>As always we are eager to hear from you! Reach out to us on <a href="https://twitter.com/SpringData">Twitter</a>, <a href="http://stackoverflow.com/tags/spring-data">Stackoverflow</a> or <a href="http://jira.spring.io">JIRA</a> to request new features, suggest improvements or report a bug.</p> - - - This Week in Spring - Tuesday October 14th, 2014 - - - - Josh Long - - tag:spring.io,2014-10-14:1789 - 2014-10-14T18:05:00Z - <p>Welcome to another installment of <em>This Week in Spring</em>! This week I've been at Silicon Valley Code Camp, JAX London and Geekout UK talking to developers about how to build scalable, microservice-centric <a href="http://start.spring.io">Spring Boot</a> applications on <a href="http://cloudfoundry.org/index.html">Cloud Foundry</a>. It's been a lot fun talking to enthusiastic developers (on both sides of the Atlantic!).</p> - -<p>Without further ado, let's get on with the roundup!</p> - -<ul> -<li>Spring Boot co-lead Phil Webb just announced the availability of <a href="https://spring.io/blog/2014/10/11/spring-boot-1-2-0-m2-available-now">Spring Boot 1.2.0.M2</a> which includes, among other things, auto-configuration for Jersey, log4j, <code>commons-dbcp</code> support, a smarter <em>disk usage</em> health indicator and improved RabbitMQ support</li> -<li>Spring and Groovy Tool Suite lead Martin Lippert <a href="https://spring.io/blog/2014/10/13/spring-tool-suite-and-groovy-grails-tool-suite-3-6-2-released">has just announced the latest and greatest release, 3.6.2</a>, which is a maintenance release that includes an update to the latest Eclipse Luna SR1 installation. </li> -<li>Also, Spring Boot co-lead <a href="https://spring.io/blog/2014/10/11/spring-boot-1-1-8-released">Phil Webb just announced the 1.1.8 release of the 1.1x line of Spring Boot</a> which includes a fix for the white-label error page cross-site scripting attack. </li> -<li>Federated security is an important part of any distributed, multi-client, (micro)service-oriented system. Spring Security and Spring Security OAuth, in particular, provide a compelling solution. Join the good Dr. Dave Syer for this <a href="https://spring.io/blog/2014/10/01/webinar-security-for-microservices-with-spring-and-oauth2">upcoming webinar on microservice security using OAuth2</a> -</li> -<li>Matt Stine will be doing a webinar introducing <a href="https://spring.io/blog/2014/10/01/webinar-architecting-for-continuous-delivery-microservices-with-pivotal-cf-and-spring-cloud">how Pivotal Cloud Foundry and Spring Cloud make for a natural solution to building microservices</a>. Don't miss this one!</li> -<li>Atlanta, GA, USA Tuesday Oct 21, Learn about Spring, Microservices, and Cloud Foundry at a <a href="http://www.pivotal.io/platform-as-a-service/cloud-platform-roadshow/atlanta#cities">one day roadshow event</a> at Cox communications.</li> -<li>Munich, Germany, GA, Thursday Oct 23, Learn about Spring, Microservices, and Cloud Foundry at a <a href="http://www.pivotal.io/platform-as-a-service/cloud-platform-roadshow/munich">one day roadshow event</a> at EMC's office in Ismaning, Germany. </li> -<li>I hope you'll join the Vaadin team and I on October 23rd for a <a href="http://spring.io/blog/2014/10/01/webinar-building-bootful-uis-with-spring-boot-and-vaadin">look how to build Spring Boot-powered Vaadin applications</a>.</li> -<li>The <em>Java et Moi</em> blog has a nice (French language) post <a href="http://javaetmoi.com/2014/10/annotation-sessionattributes-modelattribute-spring-mvc/">on using Spring MVC's <code>@SessionAttribute</code> annotation</a><br> -</li> -<li>I <em>really</em> enjoyed this <a href="http://altfatterz.blogspot.com/2014/10/software-configuration-with-spring-boot.html">very thorough look at contributing configuration property values</a> to a Spring Boot application (as <code>--D</code> arguments, environment variables, values in a property file, and values inside of JNDI)</li> -<li>Sudhir Dharmadhikari has done a <em>very</em> <a href="http://iwaow.blogspot.com/2014/10/jhipster-super-baby-in-springroos-pouch.html">nice job introducing the <code>yeoman</code> code-generator based JHipster</a>, which builds on top of <a href="http://spring.io/projects/spring-boot">Spring Boot</a>.</li> -<li>Our pal Miroslav Kopecky is back, this <a href="http://java.dzone.com/articles/scala-4-spring-mvc-without-0">time with a nice post on using Spring MVC (in Spring 4) using Java configuration</a> (through Scala!)</li> -<li> -<a href="http://antirez.com/news/79">Redis Cluster is no longer vaporware</a>! Check out the details.</li> -<li> Biju Kunjummen has put together <a href="http://java.dzone.com/articles/spring-configuration-and">a very nice post on the two styles of Java configuration</a>: one where you declare dependencies as parameters to the <code>@Bean</code>-annotated bean definition method, and one where you simply reference the other bean by calling a method.<br> -</li> -<li>Check out this post on <a href="http://architects.dzone.com/articles/using-log4j2-slf4j-spring-4">avoiding dependency conflicts between Log4j2 and SLF4J</a> in a Spring application.</li> -<li>Check out this post by Daniel Murygin which includes a detailed walk-through <a href="http://murygin.wordpress.com/2014/10/13/rest-web-service-file-uploads-spring-boot/">on building a fairly non-trivial REST service (that even handles file-uploads!) and client application using Spring Boot</a>?<br> -</li> -</ul> - - - Spring Tool Suite and Groovy/Grails Tool Suite 3.6.2 released - - - - Martin Lippert - - tag:spring.io,2014-10-13:1788 - 2014-10-13T14:20:11Z - <p>Dear Spring Community,</p> - -<p>I am happy to announce the new release of our Eclipse-based tooling today: -The Spring Tool Suite (STS) 3.6.2 and the Groovy/Grails Tool Suite (GGTS) 3.6.2.</p> - -<p>This is a maintenance release that updates STS/GGTS to the just released Eclipse Luna SR1 release. This includes a number of fixes across the various projects that are included in the STS distribution, together with fixes for the Java8 compiler and tooling in Eclipse.</p> - -<p>To download the distributions, please go visit:</p> - -<ul> -<li>Spring Tool Suite: <a href="https://spring.io/tools/sts/all">https://spring.io/tools/sts/all</a> -</li> -<li>Groovy/Grails Tool Suite: <a href="https://spring.io/tools/ggts/all">https://spring.io/tools/ggts/all</a> -</li> -</ul> - -<p>Detailed new and noteworthy notes can be found here: <a href="http://docs.spring.io/sts/nan/v362/NewAndNoteworthy.html">STS/GGTS 3.6.2 New &amp; Noteworthy</a>.</p> - -<p>NOTE: -Both tool suites ship on top of the latest Eclipse Luna 4.4 SR1 release as 64bit and 32bit based zip files only. There will be no native installers for STS/GGTS anymore.</p> - -<p>Since the 3.6.0 release we shifted towards a slightly changed release schedule, shipping minor releases more frequently. Therefore 3.6.3 is scheduled to ship in December, followed by 3.6.4 in early March 2015, shortly after the Eclipse Luna SR2 release.</p> - -<p>Enjoy!</p> - - - Spring Boot 1.2.0.M2 Available Now - - - - Phil Webb - - tag:spring.io,2014-10-11:1786 - 2014-10-11T03:55:53Z - <p>I am pleased to announce that Spring Boot 1.2.0.M2 is available now in the <a href="http://repo.springsource.org/milestone">Spring milestone repository</a>. This release adds a number of improvements and new features over <a href="https://spring.io/blog/2014/09/08/spring-boot-1-2-0-m1-available-now">M1</a>. Highlights include:</p> - -<ul> -<li>Full configuration of Jackson <code>ObjectMapper</code> features from your <code>application.properties</code> file.</li> -<li>Auto-configuration for Jersey.</li> -<li>Support for Log4j2.</li> -<li>Support for commons-dbcp2.</li> -<li>A new "disk usage" health indicator.</li> -<li>Improved RabbitMQ auto-configuration.</li> -</ul> - -<p>For a complete list of changes, and for upgrade instructions, see the <a href="http://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.2-Release-Notes">Spring Boot 1.2 Release Notes</a> on the WIKI. The <a href="http://docs.spring.io/spring-boot/docs/1.2.0.M2/reference/htmlsingle/">reference documentation</a> also continues to be updated to cover the new features.</p> - -<p>Thanks again to everyone that has contributed to the release! Please give it a go and report any problems using <a href="http://github.com/spring-projects/spring-boot/issues">the project Issue tracker</a> page.</p> - - - Spring Boot 1.1.8 released - - - - Phil Webb - - tag:spring.io,2014-10-11:1785 - 2014-10-11T00:37:52Z - <p>Spring Boot 1.1.8 has been released and is available now from <a href="http://repo.spring.io/release">repo.spring.io</a> and <a href="http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.springframework.boot%22">Maven Central</a>. </p> - -<p>This maintenance release includes a <a href="https://github.com/spring-projects/spring-boot/commit/3135c7f8aeb30b71eccc02bb0bb3817132c41060">security patch</a> to the "white label error" page which prevents potential cross-site scripting attacks; as such it is a recommended upgrade for all Spring Boot users. For a complete list of changes please refer to the <a href="https://github.com/spring-projects/spring-boot/issues?q=milestone%3A1.1.8">issue tracker</a>.</p> - -<p><a href="http://projects.spring.io/spring-boot/">Project Page</a> | <a href="https://github.com/spring-projects/spring-boot">GitHub</a> | <a href="https://github.com/spring-projects/spring-boot/issues">Issues</a> | <a href="http://docs.spring.io/spring-boot/docs/1.1.8.RELEASE/reference/htmlsingle">Documentation</a></p> - - - Pivotal at Silicon Valley Code Camp 2014 - - - - Pieter Humphrey - - tag:spring.io,2014-10-10:1784 - 2014-10-10T10:24:00Z - <p>Are you heading to Silicon Valley Code Camp 2014?   If you are, we invite all of the Java community members to stop by the Pivotal Booth and talk to Pivotal engineers about the latest innovations in Java SE, in Spring, Groovy, Grails, Redis, RabbitMQ, Tomcat, Cloud Foundry and Hadoop. The exhibit space is open Saturday 8:00am – 5:00pm, and Saturday from 8:30am to 3:30pm, so there should be plenty of time to get your questions answered.  See below for details about our sessions and awesome giveaways - come find us! </p> - -<p><strong>SATURDAY - OCTOBER 11, 2014            </strong><br> -9:45 AM </p> - -<ul> - <li>Josh Long — Spring advocate at Pivotal</li> - <li><a href="http://www.siliconvalley-codecamp.com/Session/2014/building-bootiful-applications-with-spring-boot" target="_blank">Building "Bootiful Applications with Spring Boot </a></li> - <li>Room: 8401</li> -</ul> - -<p>11:45 AM </p> - -<ul> - <li>John Hann, — Pivotal</li> - <li><a href="http://www.siliconvalley-codecamp.com/Session/2014/introducing-ravejs-zero-config-javascript-applications" target="_blank">Introducing Rave.js: Zero-config JavaScript Applications</a></li> - <li>Room: 8401</li> -</ul> - -<p>1:45 PM </p> - -<ul> - <li>Ilayaperumal Gopinathan — Pivotal</li> - <li><a href="http://www.siliconvalley-codecamp.com/Session/2014/simplifying-big-data-development-using-spring-xd" target="_blank">Simplifying Big Data development at Spring XD</a></li> - <li> Room: 8403</li> -</ul> - -<p><strong>SUNDAY - OCTOBER 12, 2014</strong></p> - -<p>9:15 AM </p> - -<ul> - <li>Cornelia Davis — Platform Engineer at Pivotal</li> - <li><a href="http://www.siliconvalley-codecamp.com/Session/2014/the-self-healing-elastic-runtime-that-is-cloud-foundry">The Self-healing, Elastic Runtime that is Cloud Foundry</a></li> - <li>Room: Room: 4302</li> -</ul> - -<p>10:45 AM</p> - -<ul> - <li>Cornelia Davis — Platform Engineer at Pivotal</li> - <li><a href="http://www.siliconvalley-codecamp.com/Session/2014/running-your-spring-apps-in-the-cloud" target="_blank">Running Your Spring Apps in the Cloud</a></li> - <li>Room: 4302</li> -</ul> - -<p>Visit us at the Pivotal Code Camp booth for technical expert conversations on Cloud Foundry, Spring, Groovy, Grails, Redis, RabbitMQ, Tomcat, Hadoop and much more. </p> - -<p>Also, don't miss the <a href="http://run.pivotal.io">Pivotal Web Services</a> Hoodie Push!  <a href="https://spring.io/guides/gs/rest-service/">Build a REST service with Spring Boot</a>, push it live to run.pivotal.io and get a hoodie!  You can do it ahead of time, and show it running to us, or use our laptops at the booth. </p> - -<p><a href="https://raw.githubusercontent.com/pieterhumphrey/springio_website_images/master/hoodie.PNG" target="_blank"><img border="0" width="215" height="254" src="https://raw.githubusercontent.com/pieterhumphrey/springio_website_images/master/hoodie.PNG" style="max-width:100%;"></a></p> - -<p> </p> - -<p> </p> - -<p>Save the date for SpringOne2GX 2015!  We hope you will mark your calendar and join us again! SpringOne2GX 2015 will be held September 14 - 17, 2015 at the Marriott Marquis in Washington DC.</p> - - - This Week in Spring - October 7th, 2014 - - - - Josh Long - - tag:spring.io,2014-10-08:1783 - 2014-10-08T03:49:00Z - <p>Welcome to another installment of <em>This Week in Spring</em>! This week, I've been at the Couchbase Connect conference talking to developers about Spring Data Couchbase (and Spring Boot, Spring XD, Spring Session, and more..). Fun show, fun crowd! Next week, I'll be at <a href="http://jaxlondon.com/2014/speakers/josh-long">JAX London</a> and <a href="http://uk.geekout.ee/speakers/josh-long/">Geekout UK</a>, so be sure to say hi if you're around. </p> - -<p>Now, with that, let's get on to the roundup..</p> - -<ol> -<li>The good Dr. Pollack just announced <a href="http://spring.io/blog/2014/10/02/spring-xd-1-0-1-released">the 1.0.1 release of Spring XD</a>, the easiest way to build data-integration and ingestion solutions. It may be only a 1.0.1 release, but make no mistake: there are some very cool features in this release, including improved administrative and administrative UI features. </li> -<li>Federated security is an important part of any distributed, multi-client, (micro)service-oriented system. Spring Security and Spring Security OAuth, in particular, provide a compelling solution. Join the good Dr. Dave Syer for this <a href="https://spring.io/blog/2014/10/01/webinar-security-for-microservices-with-spring-and-oauth2">upcoming webinar on microservice security using OAuth2</a> -</li> -<li>Matt Stine will be doing a webinar introducing <a href="https://spring.io/blog/2014/10/01/webinar-architecting-for-continuous-delivery-microservices-with-pivotal-cf-and-spring-cloud">how Pivotal Cloud Foundry and Spring Cloud make for a natural solution to building microservices</a>. Don't miss this one!</li> -<li> Spring and JavaScript ninja Brian Cavalier has written a <em>very</em> interesting post on some of <a href="http://github.com/spring-projects/spring-sync/">the work</a> we're doing towards enabling <a href="http://spring.io/blog/2014/10/08/streaming-json-patch-from-spring-to-a-react-ui">easier differential sync between JavaScript clients and services</a>. This post not only introduces all these exciting new stuff, but also builds on RaveJS, the Spring Boot-inspired approach to JavaScript.</li> -<li>I hope you'll join the Vaadin team and I on October 23rd for a <a href="http://spring.io/blog/2014/10/01/webinar-building-bootful-uis-with-spring-boot-and-vaadin">look how to build Spring Boot-powered Vaadin applications</a>.</li> -<li>Justin Lee Grant has put together <a href="http://www.justinleegrant.com/?p=489">a good introductory look at Spring Boot</a>.</li> -<li>Spring lead Juergen Hoeller just <a href="http://spring.io/blog/2014/10/01/spring-framework-4-1-1-released">announced the 4.1.1 release of Spring framework</a>. This release includes improved <code>Optional</code> handling, a Jackson <code>ObjectMapper</code> builder, some requested JDBC improvements, and much more. </li> -<li>The good Dr. Syer just announced <a href="http://spring.io/blog/2014/10/07/spring-cloud-1-0-0-m1-available-now">the first milestone release of the Spring Cloud project</a>. Spring Cloud provides primatives for building microservice and PaaS-centric applications. It builds on top of the Netflix OSS stack and Spring Boot.</li> -<li>Karthik Abram put together <a href="http://www.eclecticlogic.com/2014/09/01/classpath-scanning/">a nice post on a hidden gem in Spring: the <code>ClassPathScanningCandidateComponentProvider</code></a> class, which makes it easy to discover beans of a certain type. </li> -<li>Nicolas Lejeune has written up a fascinating look at how he managed <a href="http://labs.bsb.com/2014/09/turn-a-legacy-app-into-a-cf-service/">to convert a legacy application (it uses EJB3) and move it to a Cloud Foundry environment</a> </li> -<li>Our pal Toshiaki Maki put together <a href="http://github.com/making/spring-boot-blank">his ideal Spring Boot Maven archetype</a>, and <a href="http://twitter.com/making/status/519626091934134272">shared it</a>!<br> -</li> -<li>Are you a Groovy fan? (who isn't??) Check out Groovy project lead Guillaume LaForge's weekly roundup, <a href="http://t.co/AiDLC6novd"><em>This Week in Groovy</em></a>!</li> -<li>Do you want <a href="http://mikusa.blogspot.com/2014/08/debugging-java-applications-on.html">to debug applications deployed on Cloud Foundry</a>? Daniel Mikusa put together a very nice post explaining one approach. </li> -</ol> - - - Streaming JSON Patch from Spring to a React UI - - - - Brian Cavalier - - tag:spring.io,2014-10-07:1782 - 2014-10-08T01:47:03Z - <p>We're exploring ways to help developers create rich, modern front-ends that integrate easily with Spring back-ends. If you attended SpringOne this year, you've already seen some of the things we've been working on:</p> - -<ol> -<li> -<a href="https://speakerdeck.com/gregturn/springone2gx-2014-spring-data-rest-data-meets-hypermedia">Hypermedia support in Spring Data REST</a> presented by Greg Turnquist, Oliver Gierke, and Roy Clarkson</li> -<li> -<a href="http://www.slideshare.net/unscriptable/rave-js-springone-2gx-2014">RaveJS: Spring Boot concepts for JavaScript applications</a> by John Hann</li> -<li> -<a href="http://www.slideshare.net/briancavalier/differential-sync-and-json-patch-s2-gx-2014">Differential Synchronization and JSON Patch</a> by Craig Walls and me</li> -</ol><p>In short, We want to make it easy to communicate efficiently between a Spring back-end and a client and to easily integrate the best and most popular client-side technologies.</p> - -<h2> -<a name="user-content-react--streaming-updates" class="anchor" href="#react--streaming-updates" aria-hidden="true"><span class="octicon octicon-link"></span></a>React + streaming updates</h2> - -<p>JSON Patch is a format for sending incremental changes to structured data. I thought it would be interesting to try streaming updates in JSON Patch format via STOMP all the way out to a web UI.</p> - -<p>Craig Walls had already built a simple <a href="https://github.com/habuma/scores">football scores proof of concept</a>, using the new <a href="https://github.com/spring-projects/spring-sync/">Spring Sync</a> project to push score updates to a browser using JSON Patch over STOMP. I was able to take his POC, drop in RaveJS, add client-side reactive streams, and integrate the updates into a <a href="http://facebook.github.io/react/">React</a> UI component.</p> - -<p>You can find the <a href="https://github.com/briancavalier/scores">complete code on github in my rave-most-react branch</a>. The server is unchanged from Craig's original version. The <a href="https://github.com/briancavalier/scores/tree/rave-most-react/src/main/resources/public">web client</a> is where the action is. Have a look at the <a href="https://github.com/briancavalier/scores/blob/rave-most-react/src/main/resources/public/main.js">main.js to get an overall sense of the app</a> before we dive into some specifics.</p> - -<h2> -<a name="user-content-starting-out" class="anchor" href="#starting-out" aria-hidden="true"><span class="octicon octicon-link"></span></a>Starting out</h2> - -<p>I used <a href="https://github.com/RaveJS/rave">RaveJS</a> and npm to manage my client side dependencies, so my startup was simple:</p> - -<div class="highlight highlight-sh"><pre>&gt; <span class="nb">cd </span>src/main/resources/public - -&gt; npm init - -&lt;answer a few questions&gt; - -&gt; npm install --save rave most jiff react rave-load-jsx rave-node-process stompjs -</pre></div> - -<p>Then I just needed a single script tag in the existing HTML, and I was off to coding!</p> - -<div class="highlight highlight-html"><pre><span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"node_modules/rave/rave.js"</span><span class="nt">&gt;&lt;/script&gt;</span> -</pre></div> - -<h2> -<a name="user-content-introducing-mostjs" class="anchor" href="#introducing-mostjs" aria-hidden="true"><span class="octicon octicon-link"></span></a>Introducing most.js</h2> - -<p>Thanks to Craig, I already had a stream of updates (in JSON Patch format) flowing to the client over STOMP. I decided that the nicest way to work with the stream of patches would be to (surprise!) <em>actually use a stream</em>.</p> - -<p><a href="https://github.com/cujojs/most">Most.js</a> is cujoJS's new JavaScript reactive streams package. It provides a small, but powerful set of APIs for creating, transforming, and consuming event streams. I used it to wrap up the stompjs API.</p> - -<p>It turns out that there were two STOMP subscriptions: one that carried an initial, complete copy of all the score data, and another that carried all the subsequent changes. I was able to wrap both subscriptions up into a single reactive stream representing "the latest set of scores" by using <a href="https://github.com/cujojs/jiff">jiff.js</a> to apply the JSON Patches as they arrived.</p> - -<p>This bit of code creates a stream from a STOMP subscription to the initial data, takes the first event (a complete snapshot of all scores), and combines it with a second stream containing only JSON Patch updates to produce a view of the scores that changes over time.</p> - -<div class="highlight highlight-js"><pre><span class="kd">function</span> <span class="nx">getScoresStream</span><span class="p">(</span><span class="nx">initDestination</span><span class="p">,</span> <span class="nx">updateDestination</span><span class="p">,</span> <span class="nx">client</span><span class="p">)</span> <span class="p">{</span> - <span class="c1">// Create a stream containing one full copy of the data, and</span> - <span class="c1">// flatMap that to a stream containing the time-varying</span> - <span class="c1">// current set of scores, by accumulating each patch</span> - <span class="c1">// and emitting the updated scores data.</span> - <span class="k">return</span> <span class="nx">getInitialDataStream</span><span class="p">(</span><span class="nx">initDestination</span><span class="p">,</span> <span class="nx">client</span><span class="p">)</span> - <span class="p">.</span><span class="nx">flatMap</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span> - <span class="k">return</span> <span class="nx">getUpdatesStream</span><span class="p">(</span><span class="nx">updateDestination</span><span class="p">,</span> <span class="nx">client</span><span class="p">,</span> <span class="nx">data</span><span class="p">);</span> - <span class="p">});</span> -<span class="p">}</span> - -<span class="kd">function</span> <span class="nx">getInitialDataStream</span> <span class="p">(</span><span class="nx">initDestination</span><span class="p">,</span> <span class="nx">client</span><span class="p">)</span> <span class="p">{</span> - <span class="c1">// Await a copy of the data from the STOMP subscription</span> - <span class="c1">// that is sending the full scores data, then unsubscribe.</span> - <span class="k">return</span> <span class="nx">streamFromStompJson</span><span class="p">(</span><span class="nx">initDestination</span><span class="p">,</span> <span class="nx">client</span><span class="p">)</span> - <span class="p">.</span><span class="nx">take</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> -<span class="p">}</span> - -<span class="kd">function</span> <span class="nx">getUpdatesStream</span> <span class="p">(</span><span class="nx">updateDestination</span><span class="p">,</span> <span class="nx">client</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span> <span class="p">{</span> - <span class="c1">// Incrementally accumulate patches from the STOMP subscription</span> - <span class="c1">// that is carrying JSON Patches onto the scores data to produce</span> - <span class="c1">// an updated view of the scores.</span> - <span class="k">return</span> <span class="nx">streamFromStompJson</span><span class="p">(</span><span class="nx">updateDestination</span><span class="p">,</span> <span class="nx">client</span><span class="p">)</span> - <span class="p">.</span><span class="nx">startWith</span><span class="p">([])</span> - <span class="p">.</span><span class="nx">scan</span><span class="p">(</span><span class="nx">updateWithJsonPatch</span><span class="p">,</span> <span class="nx">data</span><span class="p">);</span> -<span class="p">}</span> -</pre></div> - -<p>Most.js also automatically cleans up underlying resources when streams end. It was easy to arrange to unsubscribe from the first subscription after an initial copy of the full scores data had arrived, leaving only one subscription: the changes.</p> - -<h2> -<a name="user-content-making-the-ui-with-react" class="anchor" href="#making-the-ui-with-react" aria-hidden="true"><span class="octicon octicon-link"></span></a>Making the UI with React</h2> - -<p>Now that I had a single most.js stream representing the latest scores, I created a <a href="https://github.com/briancavalier/scores/blob/rave-most-react/src/main/resources/public/Scoreboard.jsx">React component to display them</a>. I installed (see above) the <a href="https://github.com/KidkArolis/rave-load-jsx">rave-load-jsx extension</a>, a RaveJS extension created by a community member, which enables direct JSX component loading in RaveJS. All I had to do was create a Scoreboard.jsx file and start coding a simple React scoreboard component.</p> - -<p>React components have an internal <code>state</code> object containing the data that will be used to render the component. All I needed to do was pass the latest scores stream when creating the component, and then have the component observe the stream and update its <code>state</code>. The relevant bit of code is only a couple lines:</p> - -<div class="highlight highlight-js"><pre><span class="c1">// this.props.scores is the scores stream provided when the</span> -<span class="c1">// Scoreboard component is created</span> - -<span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">scores</span><span class="p">.</span><span class="nx">observe</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">scores</span><span class="p">)</span> <span class="p">{</span> - <span class="nx">self</span><span class="p">.</span><span class="nx">setState</span><span class="p">({</span> <span class="nx">scores</span><span class="o">:</span> <span class="nx">scores</span> <span class="p">});</span> -<span class="p">});</span> -</pre></div> - -<p>React took care of automatically keeping the DOM in sync with the <code>state</code>.</p> - -<h2> -<a name="user-content-from-bits-to-pixels" class="anchor" href="#from-bits-to-pixels" aria-hidden="true"><span class="octicon octicon-link"></span></a>From bits to pixels</h2> - -<p>This is admittedly a toy app. However, it shows quite a few powerful concepts working together in a very small space, with very little code: small, server-generated deltas flowing over STOMP + WebSocket, to a reactive stream on the client being observed by a React component. Changes are flowing from a Spring back-end through to the UI--bits to pixels, as it were.</p> - -<p>I hope this tiny app also provides a glimpse at the direction we're headed. We want to provide tools and client-side packages that help developers build rich, modern client applications that integrate with leading client-side technologies and Spring back-ends.</p> - - - Spring Cloud 1.0.0.M1 Available Now - - - - Dave Syer - - tag:spring.io,2014-10-07:1781 - 2014-10-07T13:25:00Z - <p><a href="http://projects.spring.io/spring-cloud">Spring Cloud</a> (the new umbrella project announced in September) has reached a milestone, its first, and fresh jars are available in the <a href="http://repo.spring.io/libs-milestone-local">repo.spring.io</a> repository. Spring Cloud is going to follow a "release train" model for releases, a bit like Spring Data, but we haven't got a cool name for this one yet, so it's just 1.0.0.M1. The modules that are part of this release are </p> - -<ul> -<li><p>Spring Cloud Config: Centralized external configuration management backed by a git repository. The configuration resources map directly to Spring <code>Environment</code> but could be used by non-Spring applications if desired.</p></li> -<li><p>Spring Cloud Netflix: Integration with various Netflix OSS components (Eureka, Hystrix, Zuul, Archaius, etc.).</p></li> -<li><p>Spring Cloud Bus: An event bus for linking services and service instances together with distributed messaging. Useful for propagating state changes across a cluster (e.g. config change events).</p></li> -<li><p>Spring Cloud Security: A set of primitives for building secure applications and services with minimum fuss.</p></li> -<li><p>Spring Cloud CLI: Spring Boot CLI plugin for creating Spring Cloud component applications quickly in Groovy.</p></li> -<li><p>Spring Cloud Starters: Spring Boot-style starter projects to ease dependency management for consumers of Spring Cloud.</p></li> -</ul><p>All of the above have the 1.0.0.M1 release tag, so a good starting point to try it out would be to <a href="http://projects.spring.io/spring-cloud/spring-cloud.html#_installation">install the CLI</a> and run Config Server with this code:</p> - -<div class="highlight highlight-groovy"><pre><span class="nd">@EnableConfigServer</span> -<span class="kd">class</span> <span class="nc">ConfigServer</span> <span class="o">{</span> -<span class="o">}</span> -</pre></div> - -<p>then hit <code>http://localhost:8080/foo/default</code> to see some property sources.</p> - -<p>The <a href="https://github.com/spring-cloud">code</a> is hosted on github, and community contributions are extremely welcome, so get on over there are check it out. There are some neat samples in a separate organization: <a href="https://github.com/spring-cloud-samples">spring-cloud-samples</a>, including a "scripts" project that has git submodules and scripts to get a complete demo system up and running as quickly as possible.</p> - - - Spring XD 1.0.1 released - - - - Mark Pollack - - tag:spring.io,2014-10-02:1780 - 2014-10-02T22:49:48Z - <p>On behalf of the Spring XD team, I am very pleased to announce the general availability of Spring XD 1.0.1! </p> - -<p>This release includes <a href="https://jira.spring.io/secure/ReleaseNote.jspa?projectId=11401&amp;version=14685">bug fixes and enhancements</a> as well as some new features:</p> - -<ul> -<li> -<a href="https://github.com/spring-projects/spring-xd/wiki/Application-Configuration#enabling-https">HTTPS access</a> and <a href="https://github.com/spring-projects/spring-xd/wiki/Application-Configuration#enabling-authentication">Authentication</a> to Admin Server</li> -<li> -<a href="https://github.com/spring-projects/spring-xd/wiki/AdminUI#containers">Cluster</a> and <a href="https://github.com/spring-projects/spring-xd/wiki/AdminUI#streams">Stream</a> views in UI</li> -<li>Configure a <a href="https://github.com/spring-projects/spring-xd/wiki/Modules#custom-module-registry">location for custom modules</a> -</li> -<li><a href="https://github.com/spring-projects/spring-xd/wiki/Sinks#null-sink">Null sink</a></li> -</ul><p>You can <a href="http://repo.spring.io/release/org/springframework/xd/spring-xd/1.0.1.RELEASE/spring-xd-1.0.1.RELEASE-dist.zip">download the zip distribution</a> or install on OSX <a href="https://github.com/spring-projects/spring-xd/wiki/Getting-Started#osx-homebrew-installation">using homebrew</a>. On RHEL/CentOs you can <a href="https://github.com/spring-projects/spring-xd/wiki/Getting-Started#redhatcentos-installation">install using yum</a>.</p> - -<p>Feedback is very important, so please get in touch with questions and comments via</p> - -<ul> -<li> -<a href="http://stackoverflow.com/questions/tagged/spring-xd">StackOverflow</a> <code>spring-xd</code> tag</li> -<li> -<a href="https://jira.spring.io/browse/XD/?selectedTab=com.atlassian.jira.jira-projects-plugin:summary-panel">Spring JIRA</a> or <a href="https://github.com/spring-projects/spring-xd/issues">GitHub Issues</a> -</li> -</ul> - - - Spring Framework 4.1.1 released - - - - Juergen Hoeller - - tag:spring.io,2014-10-01:1779 - 2014-10-01T13:15:00Z - <p>Dear Spring community,</p> - -<p>I'm pleased to announce that Spring Framework 4.1.1 is available now. As the <b>first maintenance release in the 4.1 line</b>, this release contains a wide range of fixes for regressions and other issues reported against 4.1 GA. A big thank you to all the issue reporters out there!</p> - -<p>4.1.1 also comes with a <b>selection of minor enhancements</b>, for example: consistent handling of Java 8's Optional type, a Jackson ObjectMapper builder class with refined defaults, some requested JDBC refinements, as well as <b>specific performance improvements</b>.</p> - -<p><a href="https://jira.spring.io/issues/?jql=project%20%3D%20SPR%20AND%20fixVersion%20%3D%204.1.1%20ORDER%20BY%20issuetype%20ASC">-&gt; List of resolved JIRA issues for Spring Framework 4.1.1</a></p> - -<p>We strongly recommend an immediate upgrade to 4.1.1 for all 4.1 GA users. The Spring Framework team is now working towards <b>Spring Framework 4.1.2 at the end of October</b>, which will be the foundation for the upcoming Spring Boot 1.2 GA release.</p> - -<p>On a related note, along with 4.1.2, we are preparing <b>Spring Framework 4.0.8 as the last 4.0.x maintenance release</b>. If there is anything you'd like to get fixed in the 4.0.x branch still, now is the time to raise it! Otherwise, please upgrade to 4.1.x for ongoing active maintenance.</p> - -<p>Cheers,</p> - -<p>Juergen</p> - - - This Week in Spring - September 30, 2014 - - - - Josh Long - - tag:spring.io,2014-10-01:1774 - 2014-10-01T03:20:00Z - <p>Welcome to another installment of <em>This Week in Spring!</em> This week <a href="http://spring.io/blog/2014/09/26/pivotal-at-javaone-2014">the Spring team is at JavaOne</a>! There's been, and will be, <em>lots</em> to see! We're also hanging out at the booth, talking to as many users as possible. Check out the link I just give listing all the cool Pivotal (and non-Pivotal) talks at JavaOne. (Ahem. Naturally, I personally would <em>love</em> it if you made <a href="http://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=3693&amp;tclass=popup">my talk - <em>Spring4TW!</em> - tomorrow morning at 8:30am at Parc 55, Cyril Magnin II/III</a>!).</p> - -<p></p><p><a href="https://raw.githubusercontent.com/joshlong/meh/master/javaone2014-boot-twis.jpg" target="_blank"><img src="https://raw.githubusercontent.com/joshlong/meh/master/javaone2014-boot-twis.jpg" style="max-width:100%;"></a></p><p>In addition to IoT, Big Data, and Microservice demos using <a href="http://projects.spring.io/spring-cloud/">NetFlixOSS on Spring</a>, students were doing the coding challenge to build a <a href="https://spring.io/guides/gs/rest-service/">REST service with Spring Boot</a> and pushed to <a href="http://run.pivotal.io">Pivotal Web Services</a> in &lt; 15 minutes to get the <a href="http://preshavedyak.com/">preshavedyak hoodie</a> from American Apparel, and learning about the best PaaS for Java available on the market today; Java 8 / Tomcat 8 support was released just days ago, and there is strong support for Spring, Groovy and Grails.</p><ul> -<li>I really liked Michael Plod's <a href="http://spring.io/blog/2014/09/26/webinar-replay-why-i-recommend-spring"><em>Why I Recommend Spring</em> webinar</a>, now available online as a replay</li> -<li>Last week, Activiti BPMN2 engine co-founder Joram Barrez and I gave a talk on <a href="http://spring.io/blog/2014/09/26/webinar-replay-process-driven-spring-applications-with-activiti">how to build process (read: workflow) centric Spring applications</a>, also now available online. </li> -<li>Tuesday, Oct 21st, 2014 join <a href="https://twitter.com/mstine">Matt Stine</a> for microservice architecture series #2: <a href="http://spring.io/blog/2014/10/01/webinar-architecting-for-continuous-delivery-microservices-with-pivotal-cf-and-spring-cloud">Architecting for Continuous Delivery: Microservices with Pivotal CF and Spring Cloud</a> -</li> -<li>Thursday, October 23, 2014, 2014 <a href="http://spring.io/blog/2014/10/01/webinar-building-bootful-uis-with-spring-boot-and-vaadin">Building “Bootful” UIs with Spring Boot and Vaadin</a> -</li> -<li>Tuesday, November 4, 2014 - microservice architecture series #3 - Join <a href="https://twitter.com/david_syer">Dr. Dave Syer</a> on <a href="http://spring.io/blog/2014/10/01/webinar-security-for-microservices-with-spring-and-oauth2">Security for Microservices with Spring and OAuth2</a> -</li> -<li>Missed microservice architecture #1? Catch the replay of <a href="http://spring.io/blog/2014/09/17/webinar-replay-building-bootiful-microservices-with-spring-boot">Building "Bootiful" Microservices with Spring Boot</a> on the Spring Developer Channel</li> -<li> -<a href="http://spring.io/blog/2014/09/26/spring-boot-1-1-7-released">Spring Boot 1.1.7 is now available</a>! </li> -<li> -<a href="http://raymondhlee.wordpress.com/2014/09/20/setup-spring-security-with-active-directory-ldap-in-spring-boot-web-application/">Setup Spring Security with Active Directory LDAP in Spring Boot Web Application</a> (I <em>just</em> got asked about this at the Spring BOF yesterday!)</li> -<li>There's been an interesting debate on microservices recently. <a href="http://blog.cleancoder.com/uncle-bob/2014/09/19/MicroServicesAndJars.html">"Uncle" Bob Martin has written up a post claiming that <code>.jar</code>s and Ruby <code>gem</code>s give you the same benefit of microservices</a>. There's a <a href="http://www.giorgiosironi.com/2014/09/microservices-are-not-jars.html">great rebuttal (which I happen to agree with..) by Giorgio Sironi on his blog</a>. There's even a nice wrapup of <a href="http://www.infoq.com/news/2014/09/microservices-shared-libraries?utm_source=infoq&amp;utm_medium=popular_links_homepage">the whole discussion on InfoQ</a>.</li> -<li>I really dig <a href="http://blog.pivotal.io/cloud-foundry-pivotal/case-studies-2/platform-wind-tunnel-part-i-heroku">Matt Stine's <em>wind tunnel</em> comparison of PaaSes</a>. Up first: Heroku. I can't wait to see subsequent posts in the series!</li> -<li>This post on using Spring Data Redis was published (and included in <em>TWiS</em>..) last year, <a href="http://www.ibm.com/developerworks/library/os-springredis/index.html">but it came up again and I still thnk it's a worthy read</a> </li> -<li>The eHarmony blog has a nice post on <a href="http://www.eharmony.com/engineering/spring-batch-admin-the-tricky-parts/#.VCtPFildUpg">how to setup Spring Batch Admin (the tricky parts..)</a> -</li> -<li>In the <em>you have to see it to beleive it</em> department, did you know there's a <a href="http://bitbucket.org/sglienke/spring4d">Spring for Delphi (Spring4D) project</a>? There are Spring-inspired C++, ColdFusion, JavaScript, .NET, Python, and numerous others. Cool to add this to the list.</li> -<li>The Intertech blog has <a href="http://www.intertech.com/Blog/spring-integration-tutorial-part-7-service-activators/">another installment on their <em>epic</em> Spring Integration tutorial</a>. This one's on <em>service activators</em> - basically the Spring Integration escape-hatch so you can call regular Java objects.</li> -<li>Benjamin Ball has a great <a href="http://java.dzone.com/articles/getting-started-rabbitmq-and">writeup on using RabbitMQ and Spring</a> </li> -<li>Yashwant Chavan has a nice post on building a simple <a href="http://www.technicalkeeda.com/spring/spring-boot-mvc-example">Spring Boot (with Spring MVC) example and editing it in Eclipse</a>. </li> -<li>Our pals at Codecentric are at it again! They've just released <a href="http://blog.codecentric.de/en/2014/09/spring-boot-admin-first-official-release/">their first cut of their <em>Spring Boot Admin</em></a>. This looks like something that would fit nicely in the <a href="http://github.com/spring-cloud/">Spring Cloud</a> project... </li> -<li> -<a href="http://prezi.com/ob4vxjmj_h1f/spring-boot/">This has to be one of the coolest Spring Boot presentations, ever</a>! Careful, I don't recommend watching it full-screen if you get motion sickness! :)</li> -<li>Are you stuck on Apache CXF but still want first-class security? This post <a href="http://java.dzone.com/articles/embedded-jetty-and-apache-cxf">looks at how to plugin Spring Security on top of CXF in minutes</a> </li> -<li>Biju Kunjummen did a nice job <a href="http://java.dzone.com/articles/spring-1">clarifying the differences between Spring's <code>WebApplicationInitializer</code> and <code>ApplicationContextInitializer</code></a> -</li> -</ul> - - - Webinar: Architecting for Continuous Delivery: Microservices with Pivotal CF and Spring Cloud - - - - Pieter Humphrey - - tag:spring.io,2014-10-01:1776 - 2014-10-01T02:20:00Z - <p>Speaker: Matt Stine, Pivotal </p> - -<p>Join Matt Stine to hear how you can architect systems that are optimized for continuous delivery, allowing you to innovate and deliver value faster and safer. Microservices, Pivotal CF, and Spring Cloud combine to create an operationalized architecture that enables enterprises to continuously deliver value at scale through rapid, iterative development, and to meet the needs of a mobile-first world.</p> - -<p>Tuesday, Oct 21st, 2014 3:00PM BST (London GMT+01:00) <a href="http://connect.pivotal.io/OSS_Webinar_MicroserviceswithPivotalCFandSpringCloud7AM_Register.html">Register</a></p> - -<p>Tuesday, Oct 21st, 2014 10:00AM PDT (San Francisco GMT-07:00) <a href="http://connect.pivotal.io/OSS_Webinar_MicroserviceswithPivotalCFandSpringCloud10AM_Register.html">Register</a></p> - - - Webinar: Building “Bootful” UIs with Spring Boot and Vaadin - - - - Pieter Humphrey - - tag:spring.io,2014-10-01:1777 - 2014-10-01T01:20:00Z - <p>Speaker: Josh Long, Pivotal and Vaadin</p> - -<p> It's been a long day, but you've done it: you've got a Spring Boot powered backend and now you need to build the UI that'll power the workforce and deliver next week. Vaadin, a UI framework that marries the ease of use of server-side Java and the rich, dynamic nature of client-side JavaScript, integrates well with Spring Boot and offers UI polish that would be hard to secure any other way. Join Spring developer advocate Josh Long and Vaadin evangelists for a look at how Vaadin and Spring Boot can get you to production quicker, and easier.</p> - -<p>Thursday, October 23, 2014, 2014 3:00PM BST (London GMT+01:00) <a href="http://connect.pivotal.io/OSS_Webinar_BuildingBootfulUIswithSpringBootandVaadin7AM_Register.html">Register</a></p> - -<p>Thursday, October 23, 2014 10:00AM PDT (San Francisco GMT-07:00) <a href="http://connect.pivotal.io/OSS_Webinar_BuildingBootfulUIswithSpringBootandVaadin10AM_Register.html">Register</a></p> - - - Webinar: Security for Microservices with Spring and OAuth2 - - - - Pieter Humphrey - - tag:spring.io,2014-10-01:1778 - 2014-10-01T01:10:00Z - <p>Speaker: Dave Syer</p> - -<p>Security for Microservices with Spring and OAuth2 OAuth2 is a lightweight security protocol that is well-suited for use with HTTP, the protocol at the heart of many modern architectures. Spring Security OAuth2 has a load of new features, not the least of which being the `@Configuration` support in version 2.0. Combine these with Spring Boot and you have a platform which can get you a secure HTTP service application in about 20 lines of code. This presentation shows how the combination of rapid development and production-ready features in the modern Spring stack are a perfect mixture for developing secure components in a system composed of microservices. We explore the new features in Spring OAuth2, guide you through the choice of which to use and when, and show how easy they are to enable quickly.</p> - -<p>Tuesday, November 4, 2014 3:00PM GMT (London GMT) <a href="http://connect.pivotal.io/OSS_Webinar_SecurityforMicroserviceswithSpringandOAuth2_7AM_Register.html">Register</a></p> - -<p>Tuesday, November 4, 2014 10:00AM PST (San Francisco GMT-08:00) <a href="http://connect.pivotal.io/OSS_Webinar_SecurityforMicroserviceswithSpringandOAuth2_10AM_Register.html">Register</a></p> - - - Webinar Replay: Why I Recommend Spring - - - - Pieter Humphrey - - tag:spring.io,2014-09-26:1773 - 2014-09-26T14:03:00Z - <p>Speaker: Michael Plod</p> - -<p>Slides: <a href="https://speakerdeck.com/mploed/pivotal-webinar-why-do-i-recommend-spring">https://speakerdeck.com/mploed/pivotal-webinar-why-do-i-recommend-spring</a></p> - -<p>Is Spring the new legacy as quite a few people tell you on their blogs? I disagree on many levels. Throughout this session I will holistically detail without any polemics why I do recommend using the Spring Framework and its ecosystem. Aspects that will be covered include: operational impacts, ecosystem, coding and road maps. This presentation is aimed at IT managers, Architects and Developers alike.</p> - -<p>Learn more about Spring IO: <a href="http://spring.io">http://spring.io</a></p> - -<p>Learn more about Spring IO Platform: <a href="http://spring.io/platform">http://spring.io/platform</a></p> - -<p></p><iframe width="420" height="315" src="//www.youtube.com/embed/z1rpWpSKtT8" frameborder="0" allowfullscreen></iframe> - - - Webinar Replay: Process Driven Spring Applications with Activiti - - - - Pieter Humphrey - - tag:spring.io,2014-09-26:1772 - 2014-09-26T13:56:00Z - <p>Speakers: Josh Long and Joram Barrez, Activiti </p> - -<p>Slides: <a href="https://speakerdeck.com/joshlong/process-driven-applications-with-spring-boot">https://speakerdeck.com/joshlong/process-driven-applications-with-spring-boot</a> </p> - -<p>Today's applications are complex, distributed systems that - taken together - produce results. Tracking the flow of work through that system, however, becomes increasingly more painful as automated- and human-driven tasks are integrated into business processes. Business can't react to what it can't see. Business can't measure what it can't see. "Workflow" describes the sequence of processes through which a piece of work passes from initiation to completion. Workflow systems, like Activiti, describe and then execute these processes. Activiti is an open-source, Apache 2-licensed workflow engine that works with Spring and Spring Boot. In this webinar, join Spring Developer Advocate Josh Long and Activiti-ninja Joram Barrez for a look at how to distill, describe and reuse complex business processes using Spring (and Spring Boot) and Activiti. </p> - -<p>Learn more about Spring Boot: <a href="http://projects.spring.io/spring-boot">http://projects.spring.io/spring-boot</a> </p> - -<p>Learn more about Activiti below! </p> - -<p>Activiti project page: <a href="http://activiti.org/">http://activiti.org/</a> </p> - -<p>Joram's blog: <a href="http://jorambarrez.com/blog">http://jorambarrez.com/blog</a> </p> - -<p>Activiti documentation: <a href="http://activiti.org/userguide/index.html">http://activiti.org/userguide/index.html</a> </p> - -<p>Activiti Github: <a href="https://github.com/Activiti/Activiti">https://github.com/Activiti/Activiti</a></p> - -<p></p><iframe width="420" height="315" src="//www.youtube.com/embed/0PV_8Lew3vg" frameborder="0" allowfullscreen></iframe> - - - Pivotal at JavaOne 2014 - - - - Pieter Humphrey - - tag:spring.io,2014-09-25:1770 - 2014-09-26T05:56:00Z - <p>Are you heading to JavaOne 2014?   If you are, we invite all of the Java community members to stop by the Pivotal Booth (Booth Number 5201) and talk to Pivotal engineers about the latest innovations in Java SE, in Spring, Groovy, Grails, Redis, RabbitMQ, Tomcat, Cloud Foundry and Hadoop. The exhibit space is open Monday, Tuesday from 9:30am – 5:30pm, and Wednesday from 9:30am to 4:30pm, so there should be plenty of time to get your questions answered.  See below for a map and booth details about our giveaways - come find us!  Lots of great stuff at the booth.</p> - -<p>Pivotal technologists are also presenting a lot of sessions as well so be sure to add the following talks to your session builder and reserve a seat:<br> -            <br> -Josh Long — Spring advocate at Pivotal</p> -<ul> -<li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=3868&amp;tclass=popup" target="_blank">The Spring BOF [BOF3868]</a></li> - <li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=3693&amp;tclass=popup" target="_blank">Spring 4TW! [CON3693]</a></li> -</ul><p>Cornelia Davis — Platform Engineer at Pivotal</p> -<ul> -<li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=4327&amp;tclass=popup" target="_blank">Running Your Spring Apps in the Cloud [CON4327]</a></li> -</ul><p>John Field — Solutions Architect at Pivotal</p> -<ul> -<li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=3478&amp;tclass=popup" target="_blank">Open Source Identity and Access Management Expert Panel, Part 3 [BOF3478]</a></li> - <li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=3479&amp;tclass=popup" target="_blank">The Anatomy of a Secure Web Application Using Java [CON3479]</a></li> -</ul><p>Guillaume Laforge — Groovy project manager at Pivotal</p> -<ul> -<li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=2939&amp;tclass=popup" target="_blank">Script Bowl 2014: The Battle Rages On [CON2939]</a></li> - <li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=5996&amp;tclass=popup" target="_blank">Groovy in 2014 and Beyond [CON5996]</a></li> - <li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=5839&amp;tclass=popup" target="_blank">Groovy in the Light of Java 8 [CON5839]</a></li> -</ul><p>Martin Lippert - Principal Software Engineer at Pivotal</p> -<ul> -<li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=1739&amp;tclass=popup" target="_blank">Connecting the Eclipse IDE to the Cloud-Based Era of Developer Tooling [CON1739]</a></li> -</ul><p>Oliver Gierke - Spring Data Project Lead at Pivotal</p> -<ul> -<li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=6071&amp;tclass=popup" target="_blank">REST Assured: Hypermedia APIs with Spring MVC [CON6071]</a></li> -</ul><p>Cédric Champeau — Senior software engineer in the Groovy team at Pivotal</p> -<ul> -<li><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=2425&amp;tclass=popup" target="_blank">Rethinking API Design with Groovy Traits [CON2425]</a></li> -</ul><p>Interesting non-Pivotal Sessions</p> -<p><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=1764" target="_blank">Groovy and Grails Puzzlers: As Usual—Traps, Pitfalls, and End Cases[CON1764]</a> <br><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=4952" target="_blank">Microservices on the JVM: A Practical Overview [CON4952]</a></p> -<p><a href="https://oracleus.activeevents.com/2014/connect/sessionDetail.ww?SESSION_ID=9447" target="_blank">Use Java, the Spring Framework, and Oracle Tuxedo to Extend Existing C/C++/COBOL Apps[HOL9447]</a> <br></p><p>Visit us at the booth for technical expert conversations on Cloud Foundry, Spring, Groovy, Grails, Redis, RabbitMQ, Tomcat, Hadoop and much more. We'll have great demos in the booth about:</p> -<ul> -<li> Java EE and PaaS with <a href="http://www.pivotal.io/platform-as-a-service/pivotal-cf">Cloud Foundry</a> via JBoss and WebLogic Buildpack demos</li> - - <li>Internet of Things, Hadoop with <a href="http://projects.spring.io/spring-xd">Spring XD</a> Demos</li> - <li> -<a href="http://microservices.io">Microservice Architecture</a> and <a href="http://www.pivotal.io/platform-as-a-service/pivotal-cf">PaaS</a> with <a href="http://projects.spring.io/spring-boot">Spring Boot</a>, <a href="http://projects.spring.io/spring-cloud">Spring Cloud</a> Demos</li> -</ul><p><a href="http://run.pivotal.io">Pivotal Web Services</a> Hoodie Push!  <a href="https://spring.io/guides/gs/rest-service/">Build a REST service with Spring Boot</a>, push it live to run.pivotal.io and get a hoodie!  You can do it ahead of time, and show it running to us, or use our laptops at the booth. </p> -<p><a href="https://raw.githubusercontent.com/pieterhumphrey/springio_website_images/master/hoodie.PNG" target="_blank"><img border="0" width="215" height="254" src="https://raw.githubusercontent.com/pieterhumphrey/springio_website_images/master/hoodie.PNG" style="max-width:100%;"></a></p> -<p> </p> -<p> </p> -<p>Save the date for SpringOne2GX 2015!  We hope you will mark your calendar and join us again! SpringOne2GX 2015 will be held September 14 - 17, 2015 at the Marriott Marquis in Washington DC.</p> -<p><a href="https://raw.githubusercontent.com/pieterhumphrey/springio_website_images/master/javaone_booth_pivotal.PNG" target="_blank"><img border="0" width="624" height="398" src="https://raw.githubusercontent.com/pieterhumphrey/springio_website_images/master/javaone_booth_pivotal.PNG" style="max-width:100%;"></a></p> -<p><a href="https://github.com/pieterhumphrey/springio_website_images/blob/master/javaone_booth_pivotal2.PNG" target="_blank"><img src="https://github.com/pieterhumphrey/springio_website_images/raw/master/javaone_booth_pivotal2.PNG" width="577" height="441" style="max-width:100%;"></a></p> -<p><br></p> - - - Spring Boot 1.1.7 released - - - - Phil Webb - - tag:spring.io,2014-09-26:1771 - 2014-09-26T04:56:15Z - <p>Spring Boot 1.1.7 has been released and is available now from <a href="http://repo.spring.io/release">repo.spring.io</a> and <a href="http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.springframework.boot%22">Maven Central</a>. </p> - -<p>This maintenance release is a recommended upgrade for all Spring Boot users. For a complete list of changes please refer to the <a href="https://github.com/spring-projects/spring-boot/issues?q=milestone%3A1.1.7">issue tracker</a>.</p> - -<p><a href="http://projects.spring.io/spring-boot/">Project Page</a> | <a href="https://github.com/spring-projects/spring-boot">GitHub</a> | <a href="https://github.com/spring-projects/spring-boot/issues">Issues</a> | <a href="http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/reference/htmlsingle">Documentation</a></p> - - - Demo: IoT Realized with Spring XD - The Connected Car - - - - Pieter Humphrey - - tag:spring.io,2014-09-25:1769 - 2014-09-24T20:59:00Z - <p>Speaker: Derek Beauregard -Contributors: Phil Berman, Darrel Sharpe, Michael Minella -In this demo we will explore the power of Spring XD in the context of the Internet of Things (IoT). We will look at a solution developed with Spring XD to stream real time analytics from a moving car using open standards. Ingestion of the real time data (location, speed, engine diagnostics, etc), analyzing it to provide highly accurate MPG and vehicle range prediction, as well as providing real time dashboards will all be covered. Watch this demo to get a sense of how Spring XD can serve as a critical building block for the IoT.</p> - -<iframe width="420" height="315" src="//www.youtube.com/embed/qkm2GV57hzY" frameborder="0" allowfullscreen></iframe> - - - diff --git a/.metadata/.plugins/org.springsource.ide.eclipse.dashboard.ui/feeds/dashboard.feeds.update/623127801.xml b/.metadata/.plugins/org.springsource.ide.eclipse.dashboard.ui/feeds/dashboard.feeds.update/623127801.xml deleted file mode 100644 index f87bdf6f7a..0000000000 --- a/.metadata/.plugins/org.springsource.ide.eclipse.dashboard.ui/feeds/dashboard.feeds.update/623127801.xml +++ /dev/null @@ -1,291 +0,0 @@ - - - - SpringSource Tool Suites Updates - http://www.springsource.com/products/sts - This feeds imforms about important updates relevant to users of STS. - Feeder 2.0.7(1195) http://reinventedsoftware.com/feeder/ - http://blogs.law.harvard.edu/tech/rss - en-us - sts@springsource.com - Mon, 13 Oct 2014 10:38:33 +0100 - Mon, 13 Oct 2014 10:38:33 +0100 - - - - - - Thanks for installing STS/GGTS 3.6.2 - http://spring.io/tools -

Pivotal has released an update to Spring Tool Suite (STS) and Groovy/Grails Tool Suite (GGTS), the best Eclipse-powered development environment for building Spring, Groovy, and Grails powered enterprise application.

-

Please review the following documents:

-
  • 3.6.2 New & Noteworthy
  • ]]>
    - Mon, 13 Oct 2014 12:13:33 +0100 - version=[3.6.2.201410090827-RELEASE,3.6.3) - - thanks-for-installing-sts-362 -
    - - - STS/GGTS 3.6.2 has been released - http://spring.io/tools -

    Pivotal has released an update to Spring Tool Suite (STS) and Groovy/Grails Tool Suite (GGTS), the best Eclipse-powered development environment for building Spring, Groovy, and Grails powered enterprise application.

    It is recommend to update as soon as possible.

    -

    Please review the following documents:

    -
  • 3.6.2 New & Noteworthy
  • ]]>
    - Mon, 13 Oct 2014 12:12:33 +0100 - version=[0,3.6.2.201410090827-RELEASE) - severity=important - sts-362-released -
    - - - - Cloud Foundry Eclipse 1.7.1 released - http://www.cloudfoundry.com -

    Pivotal has released Cloud Foundry Eclipse version 1.7.1 which features various application deployment and home page navigation improvements, and a new Cloud Routes wizard for browsing and deleting application routes. Java 7 is a required Execution Environment.

    ]]>
    - Tue, 16 Sep 2014 10:38:33 +0100 - - - bundle=!org.cloudfoundry.ide.eclipse.feature.group - cloud-foundry-integration-171-released -
    - - - - - - Patch released to fix a Xerces classloading issue - https://issuetracker.springsource.com/browse/STS-1672 -

    SpringSource has just published a patch to fix a severe issue in STS that causes parsing of Spring XML files to fail with a Xerces classloading issue.

    It is recommend to update as soon as possible. The feature patch is available from the STS Dashboard -> Extensions tab.

    -

    Get to get more details about the issue please read the following bug entries:

    -
  • Issue in the STS JIRA
  • -
  • Community forum discussion
  • We apologize that this patch did not make it into the 2.6.0 release of STS.

    ]]>
    - Mon, 21 Mar 2011 10:38:33 +0100 - version=[2.6.0.201103160035-RELEASE,2.7.0.201105101000-M1) - severity=important - bundle=!org.springframework.ide.eclipse.patch.feature.feature.group - patch-STS1672-released -
    - - - - - - - - - - -
    -
    diff --git a/.metadata/version.ini b/.metadata/version.ini deleted file mode 100644 index c51ff745b6..0000000000 --- a/.metadata/version.ini +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.core.runtime=1 \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..40f5c88746 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Eugen Paraschiv + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index f0d3d29da7..271aea0767 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,14 @@ The "REST with Spring" Classes ============================== + After 5 months of work, here's the Master Class of REST With Spring:
    **[>> THE REST WITH SPRING MASTER CLASS](http://www.baeldung.com/rest-with-spring-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=rws#master-class)** +And here's the Master Class of Learn Spring Security:
    +**[>> LEARN SPRING SECURITY MASTER CLASS](http://www.baeldung.com/learn-spring-security-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=lss#master-class)** + + Spring Tutorials ================ @@ -23,4 +28,4 @@ Any IDE can be used to work with the projects, but if you're using Eclipse, cons CI - Jenkins ================================ -This tutorials project is being built **[>> HERE](https://rest-security.ci.cloudbees.com/job/tutorials/)** +This tutorials project is being built **[>> HERE](https://rest-security.ci.cloudbees.com/job/tutorials-unit/)** diff --git a/algorithms/README.md b/algorithms/README.md index dc12b528da..5f101c296c 100644 --- a/algorithms/README.md +++ b/algorithms/README.md @@ -3,8 +3,15 @@ - [Dijkstra Algorithm in Java](http://www.baeldung.com/java-dijkstra) - [Introduction to Cobertura](http://www.baeldung.com/cobertura) - [Ant Colony Optimization](http://www.baeldung.com/java-ant-colony-optimization) -- [Validating Input With Finite Automata in Java](http://www.baeldung.com/finite-automata-java) +- [Validating Input With Finite Automata in Java](http://www.baeldung.com/java-finite-automata) - [Introduction to Jenetics Library](http://www.baeldung.com/jenetics) - [Check If a Number Is Prime in Java](http://www.baeldung.com/java-prime-numbers) - [Example of Hill Climbing Algorithm](http://www.baeldung.com/java-hill-climbing-algorithm) - [Monte Carlo Tree Search for Tic-Tac-Toe Game](http://www.baeldung.com/java-monte-carlo-tree-search) +- [String Search Algorithms for Large Texts](http://www.baeldung.com/java-full-text-search-algorithms) +- [Test a Linked List for Cyclicity](http://www.baeldung.com/java-linked-list-cyclicity) +- [Binary Search Algorithm in Java](http://www.baeldung.com/java-binary-search) +- [Bubble Sort in Java](http://www.baeldung.com/java-bubble-sort) +- [Introduction to JGraphT](http://www.baeldung.com/jgrapht) +- [Introduction to Minimax Algorithm](http://www.baeldung.com/java-minimax-algorithm) +- [How to Calculate Levenshtein Distance in Java?](http://www.baeldung.com/java-levenshtein-distance) diff --git a/algorithms/pom.xml b/algorithms/pom.xml index 967bcbc706..e972f39494 100644 --- a/algorithms/pom.xml +++ b/algorithms/pom.xml @@ -34,6 +34,11 @@ jenetics 3.7.0 + + org.jgrapht + jgrapht-core + 1.0.1 + diff --git a/algorithms/src/main/java/com/baeldung/algorithms/bubblesort/BubbleSort.java b/algorithms/src/main/java/com/baeldung/algorithms/bubblesort/BubbleSort.java new file mode 100644 index 0000000000..a561072b2e --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/bubblesort/BubbleSort.java @@ -0,0 +1,40 @@ +package com.baeldung.algorithms.bubblesort; + +import java.util.stream.IntStream; + +public class BubbleSort { + + void bubbleSort(Integer[] arr) { + int n = arr.length; + IntStream.range(0, n - 1) + .flatMap(i -> IntStream.range(i + 1, n - i)) + .forEach(j -> { + if (arr[j - 1] > arr[j]) { + int temp = arr[j]; + arr[j] = arr[j - 1]; + arr[j - 1] = temp; + } + }); + } + + void optimizedBubbleSort(Integer[] arr) { + int i = 0, n = arr.length; + + boolean swapNeeded = true; + while (i < n - 1 && swapNeeded) { + swapNeeded = false; + for (int j = 1; j < n - i; j++) { + if (arr[j - 1] > arr[j]) { + + int temp = arr[j - 1]; + arr[j - 1] = arr[j]; + arr[j] = temp; + swapNeeded = true; + } + } + if (!swapNeeded) + break; + i++; + } + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceBase.java b/algorithms/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceBase.java new file mode 100644 index 0000000000..ec66621928 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceBase.java @@ -0,0 +1,15 @@ +package com.baeldung.algorithms.editdistance; + +import java.util.Arrays; + +public class EditDistanceBase { + + static int costOfSubstitution(char a, char b) { + return a == b ? 0 : 1; + } + + static int min(int... numbers) { + return Arrays.stream(numbers) + .min().orElse(Integer.MAX_VALUE); + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceDynamicProgramming.java b/algorithms/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceDynamicProgramming.java new file mode 100644 index 0000000000..1f8824c4f4 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceDynamicProgramming.java @@ -0,0 +1,26 @@ +package com.baeldung.algorithms.editdistance; + +public class EditDistanceDynamicProgramming extends EditDistanceBase { + + static int calculate(String x, String y) { + int[][] dp = new int[x.length() + 1][y.length() + 1]; + + for (int i = 0; i <= x.length(); i++) { + for (int j = 0; j <= y.length(); j++) { + if (i == 0) + dp[i][j] = j; + + else if (j == 0) + dp[i][j] = i; + + else { + dp[i][j] = min(dp[i - 1][j - 1] + + costOfSubstitution(x.charAt(i - 1), y.charAt(j - 1)), + dp[i - 1][j] + 1, dp[i][j - 1] + 1); + } + } + } + + return dp[x.length()][y.length()]; + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceRecursive.java b/algorithms/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceRecursive.java new file mode 100644 index 0000000000..8ed48dc554 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/editdistance/EditDistanceRecursive.java @@ -0,0 +1,21 @@ +package com.baeldung.algorithms.editdistance; + +public class EditDistanceRecursive extends EditDistanceBase { + + static int calculate(String x, String y) { + + if (x.isEmpty()) { + return y.length(); + } + + if (y.isEmpty()) { + return x.length(); + } + + int substitution = calculate(x.substring(1), y.substring(1)) + costOfSubstitution(x.charAt(0), y.charAt(0)); + int insertion = calculate(x, y.substring(1)) + 1; + int deletion = calculate(x.substring(1), y) + 1; + + return min(substitution, insertion, deletion); + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForce.java b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForce.java index 532be70480..1df425ad2e 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForce.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForce.java @@ -2,9 +2,9 @@ package com.baeldung.algorithms.linkedlist; public class CycleDetectionBruteForce { - public static boolean detectCycle(Node head) { + public static CycleDetectionResult detectCycle(Node head) { if (head == null) { - return false; + return new CycleDetectionResult<>(false, null); } Node it1 = head; @@ -25,14 +25,14 @@ public class CycleDetectionBruteForce { } if (noOfTimesCurrentNodeVisited == 2) { - return true; + return new CycleDetectionResult<>(true, it1); } x--; } } - return false; + return new CycleDetectionResult<>(false, null); } } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIterators.java b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIterators.java index 7c8e038cb2..ab088de44a 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIterators.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIterators.java @@ -2,9 +2,9 @@ package com.baeldung.algorithms.linkedlist; public class CycleDetectionByFastAndSlowIterators { - public static boolean detectCycle(Node head) { + public static CycleDetectionResult detectCycle(Node head) { if (head == null) { - return false; + return new CycleDetectionResult<>(false, null); } Node slow = head; @@ -15,11 +15,11 @@ public class CycleDetectionByFastAndSlowIterators { fast = fast.next.next; if (slow == fast) { - return true; + return new CycleDetectionResult<>(true, fast); } } - return false; + return new CycleDetectionResult<>(false, null); } } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashing.java b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashing.java index 0b3f91b97c..90d5ecd711 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashing.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashing.java @@ -5,9 +5,9 @@ import java.util.Set; public class CycleDetectionByHashing { - public static boolean detectCycle(Node head) { + public static CycleDetectionResult detectCycle(Node head) { if (head == null) { - return false; + return new CycleDetectionResult<>(false, null); } Set> set = new HashSet<>(); @@ -15,13 +15,13 @@ public class CycleDetectionByHashing { while (node != null) { if (set.contains(node)) { - return true; + return new CycleDetectionResult<>(true, node); } set.add(node); node = node.next; } - return false; + return new CycleDetectionResult<>(false, null); } } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionResult.java b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionResult.java new file mode 100644 index 0000000000..e7556311b3 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleDetectionResult.java @@ -0,0 +1,12 @@ +package com.baeldung.algorithms.linkedlist; + +public class CycleDetectionResult { + boolean cycleExists; + Node node; + + public CycleDetectionResult(boolean cycleExists, Node node) { + super(); + this.cycleExists = cycleExists; + this.node = node; + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForce.java b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForce.java index cacfd44121..a2bfaee9a1 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForce.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForce.java @@ -3,26 +3,21 @@ package com.baeldung.algorithms.linkedlist; public class CycleRemovalBruteForce { public static boolean detectAndRemoveCycle(Node head) { - if (head == null) { - return false; + CycleDetectionResult result = CycleDetectionByFastAndSlowIterators.detectCycle(head); + + if (result.cycleExists) { + removeCycle(result.node, head); } - Node slow = head; - Node fast = head; - - while (fast != null && fast.next != null) { - slow = slow.next; - fast = fast.next.next; - - if (slow == fast) { - removeCycle(slow, head); - return true; - } - } - - return false; + return result.cycleExists; } + /** + * @param loopNodeParam - reference to the node where Flyods cycle + * finding algorithm ends, i.e. the fast and the slow iterators + * meet. + * @param head - reference to the head of the list + */ private static void removeCycle(Node loopNodeParam, Node head) { Node it = head; @@ -39,12 +34,12 @@ public class CycleRemovalBruteForce { private static boolean isNodeReachableFromLoopNode(Node it, Node loopNodeParam) { Node loopNode = loopNodeParam; - while (loopNode.next != loopNodeParam) { + do { if (it == loopNode) { return true; } loopNode = loopNode.next; - } + } while (loopNode.next != loopNodeParam); return false; } diff --git a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodes.java b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodes.java index afc525a8d3..d8db37fc4c 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodes.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodes.java @@ -3,28 +3,17 @@ package com.baeldung.algorithms.linkedlist; public class CycleRemovalByCountingLoopNodes { public static boolean detectAndRemoveCycle(Node head) { - if (head == null) { - return false; + CycleDetectionResult result = CycleDetectionByFastAndSlowIterators.detectCycle(head); + + if (result.cycleExists) { + removeCycle(result.node, head); } - Node slow = head; - Node fast = head; - - while (fast != null && fast.next != null) { - slow = slow.next; - fast = fast.next.next; - - if (slow == fast) { - int cycleLength = calculateCycleLength(slow); - removeCycle(head, cycleLength); - return true; - } - } - - return false; + return result.cycleExists; } - private static void removeCycle(Node head, int cycleLength) { + private static void removeCycle(Node loopNodeParam, Node head) { + int cycleLength = calculateCycleLength(loopNodeParam); Node cycleLengthAdvancedIterator = head; Node it = head; diff --git a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodes.java b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodes.java index d5b8b1cc8f..b979f7f677 100644 --- a/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodes.java +++ b/algorithms/src/main/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodes.java @@ -3,24 +3,13 @@ package com.baeldung.algorithms.linkedlist; public class CycleRemovalWithoutCountingLoopNodes { public static boolean detectAndRemoveCycle(Node head) { - if (head == null) { - return false; + CycleDetectionResult result = CycleDetectionByFastAndSlowIterators.detectCycle(head); + + if (result.cycleExists) { + removeCycle(result.node, head); } - Node slow = head; - Node fast = head; - - while (fast != null && fast.next != null) { - slow = slow.next; - fast = fast.next.next; - - if (slow == fast) { - removeCycle(slow, head); - return true; - } - } - - return false; + return result.cycleExists; } private static void removeCycle(Node meetingPointParam, Node head) { diff --git a/algorithms/src/main/java/com/baeldung/algorithms/prime/PrimeGenerator.java b/algorithms/src/main/java/com/baeldung/algorithms/prime/PrimeGenerator.java new file mode 100644 index 0000000000..48d51a8848 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/prime/PrimeGenerator.java @@ -0,0 +1,59 @@ +package com.baeldung.algorithms.prime; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class PrimeGenerator { + public static List sieveOfEratosthenes(int n) { + final boolean prime[] = new boolean[n + 1]; + Arrays.fill(prime, true); + + for (int p = 2; p * p <= n; p++) { + if (prime[p]) { + for (int i = p * 2; i <= n; i += p) + prime[i] = false; + } + } + + final List primes = new LinkedList<>(); + for (int i = 2; i <= n; i++) { + if (prime[i]) + primes.add(i); + } + return primes; + } + + public static List primeNumbersBruteForce(int max) { + final List primeNumbers = new LinkedList(); + for (int i = 2; i <= max; i++) { + if (isPrimeBruteForce(i)) { + primeNumbers.add(i); + } + } + return primeNumbers; + } + + private static boolean isPrimeBruteForce(int x) { + for (int i = 2; i < x; i++) { + if (x % i == 0) { + return false; + } + } + return true; + } + + public static List primeNumbersTill(int max) { + return IntStream.rangeClosed(2, max) + .filter(x -> isPrime(x)) + .boxed() + .collect(Collectors.toList()); + } + + private static boolean isPrime(int x) { + return IntStream.rangeClosed(2, (int) (Math.sqrt(x))) + .allMatch(n -> x % n != 0); + } +} diff --git a/algorithms/src/test/java/algorithms/MCTSTest.java b/algorithms/src/test/java/algorithms/MCTSTest.java deleted file mode 100644 index f969c26311..0000000000 --- a/algorithms/src/test/java/algorithms/MCTSTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package algorithms; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import com.baeldung.algorithms.mcts.montecarlo.MonteCarloTreeSearch; -import com.baeldung.algorithms.mcts.montecarlo.State; -import com.baeldung.algorithms.mcts.montecarlo.UCT; -import com.baeldung.algorithms.mcts.tictactoe.Board; -import com.baeldung.algorithms.mcts.tictactoe.Position; -import com.baeldung.algorithms.mcts.tree.Tree; - -public class MCTSTest { - Tree gameTree; - MonteCarloTreeSearch mcts; - - @Before - public void initGameTree() { - gameTree = new Tree(); - mcts = new MonteCarloTreeSearch(); - } - - @Test - public void givenStats_whenGetUCTForNode_thenUCTMatchesWithManualData() { - double uctValue = 15.79; - assertEquals(UCT.uctValue(600, 300, 20), uctValue, 0.01); - } - - @Test - public void giveninitBoardState_whenGetAllPossibleStates_thenNonEmptyList() { - State initState = gameTree.getRoot().getState(); - List possibleStates = initState.getAllPossibleStates(); - assertTrue(possibleStates.size() > 0); - } - - @Test - public void givenEmptyBoard_whenPerformMove_thenLessAvailablePossitions() { - Board board = new Board(); - int initAvailablePositions = board.getEmptyPositions().size(); - board.performMove(Board.P1, new Position(1, 1)); - int availablePositions = board.getEmptyPositions().size(); - assertTrue(initAvailablePositions > availablePositions); - } - - @Test - public void givenEmptyBoard_whenSimulateInterAIPlay_thenGameDraw() { - Board board = new Board(); - - int player = Board.P1; - int totalMoves = Board.DEFAULT_BOARD_SIZE * Board.DEFAULT_BOARD_SIZE; - for (int i = 0; i < totalMoves; i++) { - board = mcts.findNextMove(board, player); - if (board.checkStatus() != -1) { - break; - } - player = 3 - player; - } - int winStatus = board.checkStatus(); - assertEquals(winStatus, Board.DRAW); - } - - @Test - public void givenEmptyBoard_whenLevel1VsLevel3_thenLevel3WinsOrDraw() { - Board board = new Board(); - MonteCarloTreeSearch mcts1 = new MonteCarloTreeSearch(); - mcts1.setLevel(1); - MonteCarloTreeSearch mcts3 = new MonteCarloTreeSearch(); - mcts3.setLevel(3); - - int player = Board.P1; - int totalMoves = Board.DEFAULT_BOARD_SIZE * Board.DEFAULT_BOARD_SIZE; - for (int i = 0; i < totalMoves; i++) { - if (player == Board.P1) - board = mcts3.findNextMove(board, player); - else - board = mcts1.findNextMove(board, player); - - if (board.checkStatus() != -1) { - break; - } - player = 3 - player; - } - int winStatus = board.checkStatus(); - assertTrue(winStatus == Board.DRAW || winStatus == Board.P1); - } - -} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortTest.java b/algorithms/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortTest.java new file mode 100644 index 0000000000..7774eb3e67 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/bubblesort/BubbleSortTest.java @@ -0,0 +1,26 @@ +package com.baeldung.algorithms.bubblesort; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class BubbleSortTest { + + @Test + public void givenIntegerArray_whenSortedWithBubbleSort_thenGetSortedArray() { + Integer[] array = { 2, 1, 4, 6, 3, 5 }; + Integer[] sortedArray = { 1, 2, 3, 4, 5, 6 }; + BubbleSort bubbleSort = new BubbleSort(); + bubbleSort.bubbleSort(array); + assertArrayEquals(array, sortedArray); + } + + @Test + public void givenIntegerArray_whenSortedWithOptimizedBubbleSort_thenGetSortedArray() { + Integer[] array = { 2, 1, 4, 6, 3, 5 }; + Integer[] sortedArray = { 1, 2, 3, 4, 5, 6 }; + BubbleSort bubbleSort = new BubbleSort(); + bubbleSort.optimizedBubbleSort(array); + assertArrayEquals(array, sortedArray); + } +} \ No newline at end of file diff --git a/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceDataProvider.java b/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceDataProvider.java new file mode 100644 index 0000000000..89bd871616 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceDataProvider.java @@ -0,0 +1,21 @@ +package com.baeldung.algorithms.editdistance; + +import org.junit.runners.Parameterized.Parameters; + +import java.util.Arrays; +import java.util.Collection; + +public class EditDistanceDataProvider { + + @Parameters + public static Collection getLists() { + return Arrays.asList(new Object[][] { + { "", "", 0 }, + { "ago", "", 3 }, + { "", "do", 2 }, + { "abc", "adc", 1 }, + { "peek", "pesek", 1 }, + { "sunday", "saturday", 3 } + }); + } +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceTest.java b/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceTest.java new file mode 100644 index 0000000000..bab2f480a5 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/editdistance/EditDistanceTest.java @@ -0,0 +1,32 @@ +package com.baeldung.algorithms.editdistance; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import static org.junit.Assert.assertEquals; + +@RunWith(Parameterized.class) +public class EditDistanceTest extends EditDistanceDataProvider { + + private String x; + private String y; + private int result; + + public EditDistanceTest(String a, String b, int res) { + super(); + x = a; + y = b; + result = res; + } + + @Test + public void testEditDistance_RecursiveImplementation() { + assertEquals(result, EditDistanceRecursive.calculate(x, y)); + } + + @Test + public void testEditDistance_givenDynamicProgrammingImplementation() { + assertEquals(result, EditDistanceDynamicProgramming.calculate(x, y)); + } +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceTest.java index 09250a8a66..7f9b8acdbd 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionBruteForceTest.java @@ -2,19 +2,22 @@ package com.baeldung.algorithms.linkedlist; import org.junit.Assert; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +@RunWith(value = Parameterized.class) public class CycleDetectionBruteForceTest extends CycleDetectionTestBase { + boolean cycleExists; + Node head; - @Test - public void givenNormalList_dontDetectLoop() { - Node root = createList(); - Assert.assertFalse(CycleDetectionBruteForce.detectCycle(root)); + public CycleDetectionBruteForceTest(Node head, boolean cycleExists) { + super(); + this.cycleExists = cycleExists; + this.head = head; } @Test - public void givenCyclicList_detectLoop() { - Node root = createList(); - createLoop(root); - Assert.assertTrue(CycleDetectionBruteForce.detectCycle(root)); + public void givenList_detectLoop() { + Assert.assertEquals(cycleExists, CycleDetectionBruteForce.detectCycle(head).cycleExists); } } diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsTest.java index cfe00aaefc..17d339bc33 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByFastAndSlowIteratorsTest.java @@ -2,19 +2,22 @@ package com.baeldung.algorithms.linkedlist; import org.junit.Assert; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +@RunWith(value = Parameterized.class) public class CycleDetectionByFastAndSlowIteratorsTest extends CycleDetectionTestBase { + boolean cycleExists; + Node head; - @Test - public void givenNormalList_dontDetectLoop() { - Node root = createList(); - Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(root)); + public CycleDetectionByFastAndSlowIteratorsTest(Node head, boolean cycleExists) { + super(); + this.cycleExists = cycleExists; + this.head = head; } @Test - public void givenCyclicList_detectLoop() { - Node root = createList(); - createLoop(root); - Assert.assertTrue(CycleDetectionByFastAndSlowIterators.detectCycle(root)); + public void givenList_detectLoop() { + Assert.assertEquals(cycleExists, CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists); } } diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingTest.java index af9a8239ef..73a2cc7861 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionByHashingTest.java @@ -2,19 +2,22 @@ package com.baeldung.algorithms.linkedlist; import org.junit.Assert; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +@RunWith(value = Parameterized.class) public class CycleDetectionByHashingTest extends CycleDetectionTestBase { + boolean cycleExists; + Node head; - @Test - public void givenNormalList_dontDetectLoop() { - Node root = createList(); - Assert.assertFalse(CycleDetectionByHashing.detectCycle(root)); + public CycleDetectionByHashingTest(Node head, boolean cycleExists) { + super(); + this.cycleExists = cycleExists; + this.head = head; } @Test - public void givenCyclicList_detectLoop() { - Node root = createList(); - createLoop(root); - Assert.assertTrue(CycleDetectionByHashing.detectCycle(root)); + public void givenList_detectLoop() { + Assert.assertEquals(cycleExists, CycleDetectionByHashing.detectCycle(head).cycleExists); } } diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionTestBase.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionTestBase.java index 2abf5de1d4..51906de8e5 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionTestBase.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleDetectionTestBase.java @@ -1,7 +1,22 @@ package com.baeldung.algorithms.linkedlist; +import java.util.Arrays; +import java.util.Collection; + +import org.junit.runners.Parameterized.Parameters; + public class CycleDetectionTestBase { + @Parameters + public static Collection getLists() { + return Arrays.asList(new Object[][] { + { createList(), false }, + { createListWithLoop(), true }, + { createListWithFullCycle(), true }, + { createListWithSingleNodeInCycle(), true } + }); + } + public static Node createList() { Node root = Node.createNewNode(10, null); @@ -13,6 +28,26 @@ public class CycleDetectionTestBase { return root; } + public static Node createListWithLoop() { + Node node = createList(); + createLoop(node); + return node; + } + + public static Node createListWithFullCycle() { + Node head = createList(); + Node tail = Node.getTail(head); + tail.next = head; + return head; + } + + public static Node createListWithSingleNodeInCycle() { + Node head = createList(); + Node tail = Node.getTail(head); + tail.next = tail; + return head; + } + public static void createLoop(Node root) { Node tail = Node.getTail(root); diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceTest.java index b32f20fb75..6484c9988e 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalBruteForceTest.java @@ -2,20 +2,23 @@ package com.baeldung.algorithms.linkedlist; import org.junit.Assert; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +@RunWith(value = Parameterized.class) public class CycleRemovalBruteForceTest extends CycleDetectionTestBase { + boolean cycleExists; + Node head; - @Test - public void givenNormalList_dontDetectLoop() { - Node root = createList(); - Assert.assertFalse(CycleRemovalBruteForce.detectAndRemoveCycle(root)); + public CycleRemovalBruteForceTest(Node head, boolean cycleExists) { + super(); + this.cycleExists = cycleExists; + this.head = head; } @Test - public void givenCyclicList_detectAndRemoveLoop() { - Node root = createList(); - createLoop(root); - Assert.assertTrue(CycleRemovalBruteForce.detectAndRemoveCycle(root)); - Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(root)); + public void givenList_ifLoopExists_thenDetectAndRemoveLoop() { + Assert.assertEquals(cycleExists, CycleRemovalBruteForce.detectAndRemoveCycle(head)); + Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists); } } diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesTest.java index dd938afae1..7bfd89c502 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalByCountingLoopNodesTest.java @@ -2,20 +2,23 @@ package com.baeldung.algorithms.linkedlist; import org.junit.Assert; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +@RunWith(value = Parameterized.class) public class CycleRemovalByCountingLoopNodesTest extends CycleDetectionTestBase { + boolean cycleExists; + Node head; - @Test - public void givenNormalList_dontDetectLoop() { - Node root = createList(); - Assert.assertFalse(CycleRemovalByCountingLoopNodes.detectAndRemoveCycle(root)); + public CycleRemovalByCountingLoopNodesTest(Node head, boolean cycleExists) { + super(); + this.cycleExists = cycleExists; + this.head = head; } @Test - public void givenCyclicList_detectAndRemoveLoop() { - Node root = createList(); - createLoop(root); - Assert.assertTrue(CycleRemovalByCountingLoopNodes.detectAndRemoveCycle(root)); - Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(root)); + public void givenList_ifLoopExists_thenDetectAndRemoveLoop() { + Assert.assertEquals(cycleExists, CycleRemovalByCountingLoopNodes.detectAndRemoveCycle(head)); + Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists); } } diff --git a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesTest.java b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesTest.java index 56a08a5ee4..c77efb3e3e 100644 --- a/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesTest.java +++ b/algorithms/src/test/java/com/baeldung/algorithms/linkedlist/CycleRemovalWithoutCountingLoopNodesTest.java @@ -2,20 +2,23 @@ package com.baeldung.algorithms.linkedlist; import org.junit.Assert; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +@RunWith(value = Parameterized.class) public class CycleRemovalWithoutCountingLoopNodesTest extends CycleDetectionTestBase { + boolean cycleExists; + Node head; - @Test - public void givenNormalList_dontDetectLoop() { - Node root = createList(); - Assert.assertFalse(CycleRemovalWithoutCountingLoopNodes.detectAndRemoveCycle(root)); + public CycleRemovalWithoutCountingLoopNodesTest(Node head, boolean cycleExists) { + super(); + this.cycleExists = cycleExists; + this.head = head; } @Test - public void givenCyclicList_detectAndRemoveLoop() { - Node root = createList(); - createLoop(root); - Assert.assertTrue(CycleRemovalWithoutCountingLoopNodes.detectAndRemoveCycle(root)); - Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(root)); + public void givenList_ifLoopExists_thenDetectAndRemoveLoop() { + Assert.assertEquals(cycleExists, CycleRemovalWithoutCountingLoopNodes.detectAndRemoveCycle(head)); + Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists); } } \ No newline at end of file diff --git a/algorithms/src/test/java/com/baeldung/algorithms/prime/PrimeGeneratorTest.java b/algorithms/src/test/java/com/baeldung/algorithms/prime/PrimeGeneratorTest.java new file mode 100644 index 0000000000..4995e938b7 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/prime/PrimeGeneratorTest.java @@ -0,0 +1,28 @@ +package com.baeldung.algorithms.prime; + +import static com.baeldung.algorithms.prime.PrimeGenerator.*; + +import java.util.Arrays; +import java.util.List; +import org.junit.Test; +import static org.junit.Assert.*; + +public class PrimeGeneratorTest { + @Test + public void whenBruteForced_returnsSuccessfully() { + final List primeNumbers = primeNumbersBruteForce(20); + assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers); + } + + @Test + public void whenOptimized_returnsSuccessfully() { + final List primeNumbers = primeNumbersTill(20); + assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers); + } + + @Test + public void whenSieveOfEratosthenes_returnsSuccessfully() { + final List primeNumbers = sieveOfEratosthenes(20); + assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers); + } +} diff --git a/algorithms/src/test/java/com/baeldung/jgrapht/CompleteGraphTest.java b/algorithms/src/test/java/com/baeldung/jgrapht/CompleteGraphTest.java new file mode 100644 index 0000000000..c085d54689 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/jgrapht/CompleteGraphTest.java @@ -0,0 +1,38 @@ +package com.baeldung.jgrapht; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.jgrapht.VertexFactory; +import org.jgrapht.alg.HamiltonianCycle; +import org.jgrapht.generate.CompleteGraphGenerator; +import org.jgrapht.graph.DefaultEdge; +import org.jgrapht.graph.SimpleWeightedGraph; +import org.junit.Before; +import org.junit.Test; + +public class CompleteGraphTest { + + static SimpleWeightedGraph completeGraph; + static int size = 10; + + @Before + public void createCompleteGraph() { + completeGraph = new SimpleWeightedGraph<>(DefaultEdge.class); + CompleteGraphGenerator completeGenerator = new CompleteGraphGenerator(size); + VertexFactory vFactory = new VertexFactory() { + private int id = 0; + public String createVertex() { + return "v" + id++; + } + }; + completeGenerator.generateGraph(completeGraph, vFactory, null); + } + + @Test + public void givenCompleteGraph_whenGetHamiltonianCyclePath_thenGetVerticeListInSequence() { + List verticeList = HamiltonianCycle.getApproximateOptimalForCompleteGraph(completeGraph); + assertEquals(verticeList.size(), completeGraph.vertexSet().size()); + } +} diff --git a/algorithms/src/test/java/com/baeldung/jgrapht/DirectedGraphTests.java b/algorithms/src/test/java/com/baeldung/jgrapht/DirectedGraphTests.java new file mode 100644 index 0000000000..7f4cc99715 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/jgrapht/DirectedGraphTests.java @@ -0,0 +1,95 @@ +package com.baeldung.jgrapht; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.IntStream; + +import org.jgrapht.DirectedGraph; +import org.jgrapht.GraphPath; +import org.jgrapht.alg.CycleDetector; +import org.jgrapht.alg.KosarajuStrongConnectivityInspector; +import org.jgrapht.alg.interfaces.StrongConnectivityAlgorithm; +import org.jgrapht.alg.shortestpath.AllDirectedPaths; +import org.jgrapht.alg.shortestpath.BellmanFordShortestPath; +import org.jgrapht.alg.shortestpath.DijkstraShortestPath; +import org.jgrapht.graph.DefaultDirectedGraph; +import org.jgrapht.graph.DefaultEdge; +import org.jgrapht.graph.DirectedSubgraph; +import org.jgrapht.traverse.BreadthFirstIterator; +import org.jgrapht.traverse.DepthFirstIterator; +import org.junit.Before; +import org.junit.Test; + +public class DirectedGraphTests { + DirectedGraph directedGraph; + + @Before + public void createDirectedGraph() { + directedGraph = new DefaultDirectedGraph(DefaultEdge.class); + IntStream.range(1, 10).forEach(i -> { + directedGraph.addVertex("v" + i); + }); + directedGraph.addEdge("v1", "v2"); + directedGraph.addEdge("v2", "v4"); + directedGraph.addEdge("v4", "v3"); + directedGraph.addEdge("v3", "v1"); + directedGraph.addEdge("v5", "v4"); + directedGraph.addEdge("v5", "v6"); + directedGraph.addEdge("v6", "v7"); + directedGraph.addEdge("v7", "v5"); + directedGraph.addEdge("v8", "v5"); + directedGraph.addEdge("v9", "v8"); + } + + @Test + public void givenDirectedGraph_whenGetStronglyConnectedSubgraphs_thenPathExistsBetweenStronglyconnectedVertices() { + StrongConnectivityAlgorithm scAlg = new KosarajuStrongConnectivityInspector<>(directedGraph); + List> stronglyConnectedSubgraphs = scAlg.stronglyConnectedSubgraphs(); + List stronglyConnectedVertices = new ArrayList<>(stronglyConnectedSubgraphs.get(3).vertexSet()); + + String randomVertex1 = stronglyConnectedVertices.get(0); + String randomVertex2 = stronglyConnectedVertices.get(3); + AllDirectedPaths allDirectedPaths = new AllDirectedPaths<>(directedGraph); + + List> possiblePathList = allDirectedPaths.getAllPaths(randomVertex1, randomVertex2, false, stronglyConnectedVertices.size()); + assertTrue(possiblePathList.size() > 0); + } + + @Test + public void givenDirectedGraphWithCycle_whenCheckCycles_thenDetectCycles() { + CycleDetector cycleDetector = new CycleDetector(directedGraph); + assertTrue(cycleDetector.detectCycles()); + Set cycleVertices = cycleDetector.findCycles(); + assertTrue(cycleVertices.size() > 0); + } + + @Test + public void givenDirectedGraph_whenCreateInstanceDepthFirstIterator_thenGetIterator() { + DepthFirstIterator depthFirstIterator = new DepthFirstIterator<>(directedGraph); + assertNotNull(depthFirstIterator); + } + + @Test + public void givenDirectedGraph_whenCreateInstanceBreadthFirstIterator_thenGetIterator() { + BreadthFirstIterator breadthFirstIterator = new BreadthFirstIterator<>(directedGraph); + assertNotNull(breadthFirstIterator); + } + + @Test + public void givenDirectedGraph_whenGetDijkstraShortestPath_thenGetNotNullPath() { + DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(directedGraph); + List shortestPath = dijkstraShortestPath.getPath("v1", "v4").getVertexList(); + assertNotNull(shortestPath); + } + + @Test + public void givenDirectedGraph_whenGetBellmanFordShortestPath_thenGetNotNullPath() { + BellmanFordShortestPath bellmanFordShortestPath = new BellmanFordShortestPath(directedGraph); + List shortestPath = bellmanFordShortestPath.getPath("v1", "v4").getVertexList(); + assertNotNull(shortestPath); + } +} diff --git a/algorithms/src/test/java/com/baeldung/jgrapht/EulerianCircuitTest.java b/algorithms/src/test/java/com/baeldung/jgrapht/EulerianCircuitTest.java new file mode 100644 index 0000000000..6f0fb92ab7 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/jgrapht/EulerianCircuitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.jgrapht; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.stream.IntStream; + +import org.jgrapht.GraphPath; +import org.jgrapht.alg.cycle.HierholzerEulerianCycle; +import org.jgrapht.graph.DefaultEdge; +import org.jgrapht.graph.SimpleWeightedGraph; +import org.junit.Before; +import org.junit.Test; + +public class EulerianCircuitTest { + SimpleWeightedGraph simpleGraph; + + @Before + public void createGraphWithEulerianCircuit() { + simpleGraph = new SimpleWeightedGraph<>(DefaultEdge.class); + IntStream.range(1, 6).forEach(i -> { + simpleGraph.addVertex("v" + i); + }); + IntStream.range(1, 6).forEach(i -> { + int endVertexNo = (i + 1) > 5 ? 1 : i + 1; + simpleGraph.addEdge("v" + i, "v" + endVertexNo); + }); + } + + @Test + public void givenGraph_whenCheckEluerianCycle_thenGetResult() { + HierholzerEulerianCycle eulerianCycle = new HierholzerEulerianCycle<>(); + assertTrue(eulerianCycle.isEulerian(simpleGraph)); + } + + @Test + public void givenGraphWithEulerianCircuit_whenGetEulerianCycle_thenGetGraphPath() { + HierholzerEulerianCycle eulerianCycle = new HierholzerEulerianCycle<>(); + GraphPath path = eulerianCycle.getEulerianCycle(simpleGraph); + assertTrue(path.getEdgeList().containsAll(simpleGraph.edgeSet())); + } +} diff --git a/animal-sniffer-mvn-plugin/README.md b/animal-sniffer-mvn-plugin/README.md new file mode 100644 index 0000000000..4c7c381da4 --- /dev/null +++ b/animal-sniffer-mvn-plugin/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +[Introduction to Animal Sniffer Maven Plugin](http://www.baeldung.com/maven-animal-sniffer) diff --git a/animal-sniffer-mvn-plugin/pom.xml b/animal-sniffer-mvn-plugin/pom.xml new file mode 100644 index 0000000000..3190950d9b --- /dev/null +++ b/animal-sniffer-mvn-plugin/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + com.baeldung + animal-sniffer-mvn-plugin + jar + 1.0-SNAPSHOT + example-animal-sniffer-mvn-plugin + http://maven.apache.org + + + 3.6.0 + + + + + junit + junit + 3.8.1 + test + + + + + + maven-compiler-plugin + 3.7.0 + + 1.6 + 1.6 + + + + org.codehaus.mojo + animal-sniffer-maven-plugin + 1.16 + + + org.codehaus.mojo.signature + java16 + 1.0 + + + + + animal-sniffer + verify + + check + + + + + + + + \ No newline at end of file diff --git a/animal-sniffer-mvn-plugin/src/main/java/com/baeldung/App.java b/animal-sniffer-mvn-plugin/src/main/java/com/baeldung/App.java new file mode 100644 index 0000000000..6deaf70cde --- /dev/null +++ b/animal-sniffer-mvn-plugin/src/main/java/com/baeldung/App.java @@ -0,0 +1,16 @@ +package com.baeldung; + +//import java.nio.charset.StandardCharsets; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + //System.out.println(StandardCharsets.UTF_8.name()); + } +} diff --git a/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppTest.java b/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppTest.java new file mode 100644 index 0000000000..8ecb1bc629 --- /dev/null +++ b/animal-sniffer-mvn-plugin/src/test/java/com/baeldung/AppTest.java @@ -0,0 +1,40 @@ +package com.baeldung; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + + assertTrue( true ); + + } +} diff --git a/apache-cayenne/README.md b/apache-cayenne/README.md new file mode 100644 index 0000000000..610d1233b7 --- /dev/null +++ b/apache-cayenne/README.md @@ -0,0 +1,4 @@ +## Relevant articles: + +- [Advanced Querying in Apache Cayenne](http://www.baeldung.com/apache-cayenne-query) +- [Introduction to Apache Cayenne ORM](http://www.baeldung.com/apache-cayenne-orm) diff --git a/apache-cayenne/pom.xml b/apache-cayenne/pom.xml new file mode 100644 index 0000000000..52631e8594 --- /dev/null +++ b/apache-cayenne/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + apache-cayenne + 0.0.1-SNAPSHOT + jar + + apache-cayenne + Introduction to Apache Cayenne + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + UTF-8 + UTF-8 + 1.8 + 5.1.44 + 4.0.M5 + 4.12 + + + + + org.apache.cayenne + cayenne-server + ${cayenne.version} + + + mysql + mysql-connector-java + ${mysql.connector.version} + runtime + + + + junit + junit + ${junit.version} + test + + + + + + + org.apache.cayenne.plugins + cayenne-modeler-maven-plugin + ${cayenne.version} + + + + + diff --git a/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/Article.java b/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/Article.java new file mode 100644 index 0000000000..303c180887 --- /dev/null +++ b/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/Article.java @@ -0,0 +1,9 @@ +package com.baeldung.apachecayenne.persistent; + +import com.baeldung.apachecayenne.persistent.auto._Article; + +public class Article extends _Article { + + private static final long serialVersionUID = 1L; + +} diff --git a/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/Author.java b/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/Author.java new file mode 100644 index 0000000000..5a8df57c6e --- /dev/null +++ b/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/Author.java @@ -0,0 +1,9 @@ +package com.baeldung.apachecayenne.persistent; + +import com.baeldung.apachecayenne.persistent.auto._Author; + +public class Author extends _Author { + + private static final long serialVersionUID = 1L; + +} diff --git a/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/auto/_Article.java b/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/auto/_Article.java new file mode 100644 index 0000000000..f6c179fcfd --- /dev/null +++ b/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/auto/_Article.java @@ -0,0 +1,47 @@ +package com.baeldung.apachecayenne.persistent.auto; + +import org.apache.cayenne.CayenneDataObject; +import org.apache.cayenne.exp.Property; + +import com.baeldung.apachecayenne.persistent.Author; + +/** + * Class _Article was generated by Cayenne. + * It is probably a good idea to avoid changing this class manually, + * since it may be overwritten next time code is regenerated. + * If you need to make any customizations, please use subclass. + */ +public abstract class _Article extends CayenneDataObject { + + private static final long serialVersionUID = 1L; + + public static final String ID_PK_COLUMN = "id"; + + public static final Property CONTENT = Property.create("content", String.class); + public static final Property TITLE = Property.create("title", String.class); + public static final Property AUTHOR = Property.create("author", Author.class); + + public void setContent(String content) { + writeProperty("content", content); + } + public String getContent() { + return (String)readProperty("content"); + } + + public void setTitle(String title) { + writeProperty("title", title); + } + public String getTitle() { + return (String)readProperty("title"); + } + + public void setAuthor(Author author) { + setToOneTarget("author", author, true); + } + + public Author getAuthor() { + return (Author)readProperty("author"); + } + + +} diff --git a/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/auto/_Author.java b/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/auto/_Author.java new file mode 100644 index 0000000000..4d3bb090ca --- /dev/null +++ b/apache-cayenne/src/main/java/com/baeldung/apachecayenne/persistent/auto/_Author.java @@ -0,0 +1,44 @@ +package com.baeldung.apachecayenne.persistent.auto; + +import java.util.List; + +import org.apache.cayenne.CayenneDataObject; +import org.apache.cayenne.exp.Property; + +import com.baeldung.apachecayenne.persistent.Article; + +/** + * Class _Author was generated by Cayenne. + * It is probably a good idea to avoid changing this class manually, + * since it may be overwritten next time code is regenerated. + * If you need to make any customizations, please use subclass. + */ +public abstract class _Author extends CayenneDataObject { + + private static final long serialVersionUID = 1L; + + public static final String ID_PK_COLUMN = "id"; + + public static final Property NAME = Property.create("name", String.class); + public static final Property> ARTICLES = Property.create("articles", List.class); + + public void setName(String name) { + writeProperty("name", name); + } + public String getName() { + return (String)readProperty("name"); + } + + public void addToArticles(Article obj) { + addToManyTarget("articles", obj, true); + } + public void removeFromArticles(Article obj) { + removeToManyTarget("articles", obj, true); + } + @SuppressWarnings("unchecked") + public List
    getArticles() { + return (List
    )readProperty("articles"); + } + + +} diff --git a/apache-cayenne/src/main/resources/cayenne-project.xml b/apache-cayenne/src/main/resources/cayenne-project.xml new file mode 100644 index 0000000000..3f3c59e0e9 --- /dev/null +++ b/apache-cayenne/src/main/resources/cayenne-project.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/apache-cayenne/src/main/resources/datamap.map.xml b/apache-cayenne/src/main/resources/datamap.map.xml new file mode 100644 index 0000000000..3305649669 --- /dev/null +++ b/apache-cayenne/src/main/resources/datamap.map.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneAdvancedOperationTests.java b/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneAdvancedOperationTests.java new file mode 100644 index 0000000000..cd563b6270 --- /dev/null +++ b/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneAdvancedOperationTests.java @@ -0,0 +1,256 @@ +package com.baeldung.apachecayenne; + +import com.baeldung.apachecayenne.persistent.Author; +import org.apache.cayenne.ObjectContext; +import org.apache.cayenne.QueryResponse; +import org.apache.cayenne.configuration.server.ServerRuntime; +import org.apache.cayenne.exp.Expression; +import org.apache.cayenne.exp.ExpressionFactory; +import org.apache.cayenne.query.*; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class CayenneAdvancedOperationTests { + private static ObjectContext context = null; + + @BeforeClass + public static void setupTheCayenneContext() { + ServerRuntime cayenneRuntime = ServerRuntime.builder() + .addConfig("cayenne-project.xml") + .build(); + context = cayenneRuntime.newContext(); + } + + @Before + public void saveThreeAuthors() { + Author authorOne = context.newObject(Author.class); + authorOne.setName("Paul Xavier"); + Author authorTwo = context.newObject(Author.class); + authorTwo.setName("pAuL Smith"); + Author authorThree = context.newObject(Author.class); + authorThree.setName("Vicky Sarra"); + context.commitChanges(); + } + + @After + public void deleteAllAuthors() { + SQLTemplate deleteAuthors = new SQLTemplate(Author.class, "delete from author"); + context.performGenericQuery(deleteAuthors); + } + + @Test + public void givenAuthors_whenFindAllSQLTmplt_thenWeGetThreeAuthors() { + SQLTemplate select = new SQLTemplate(Author.class, "select * from Author"); + List authors = context.performQuery(select); + + assertEquals(authors.size(), 3); + } + + @Test + public void givenAuthors_whenFindByNameSQLTmplt_thenWeGetOneAuthor() { + SQLTemplate select = new SQLTemplate(Author.class, "select * from Author where name = 'Vicky Sarra'"); + List authors = context.performQuery(select); + Author author = authors.get(0); + + assertEquals(authors.size(), 1); + assertEquals(author.getName(), "Vicky Sarra"); + } + + @Test + public void givenAuthors_whenLikeSltQry_thenWeGetOneAuthor() { + Expression qualifier = ExpressionFactory.likeExp(Author.NAME.getName(), "Paul%"); + SelectQuery query = new SelectQuery(Author.class, qualifier); + List authorsTwo = context.performQuery(query); + + assertEquals(authorsTwo.size(), 1); + } + + @Test + public void givenAuthors_whenCtnsIgnorCaseSltQry_thenWeGetTwoAuthors() { + Expression qualifier = ExpressionFactory.containsIgnoreCaseExp(Author.NAME.getName(), "Paul"); + SelectQuery query = new SelectQuery(Author.class, qualifier); + List authors = context.performQuery(query); + + assertEquals(authors.size(), 2); + } + + @Test + public void givenAuthors_whenCtnsIgnorCaseEndsWSltQry_thenWeGetTwoAuthors() { + Expression qualifier = ExpressionFactory.containsIgnoreCaseExp(Author.NAME.getName(), "Paul") + .andExp(ExpressionFactory.endsWithExp(Author.NAME.getName(), "h")); + SelectQuery query = new SelectQuery(Author.class, qualifier); + List authors = context.performQuery(query); + + Author author = authors.get(0); + + assertEquals(authors.size(), 1); + assertEquals(author.getName(), "pAuL Smith"); + } + + @Test + public void givenAuthors_whenAscOrderingSltQry_thenWeGetOrderedAuthors() { + SelectQuery query = new SelectQuery(Author.class); + query.addOrdering(Author.NAME.asc()); + + List authors = query.select(context); + Author firstAuthor = authors.get(0); + + assertEquals(authors.size(), 3); + assertEquals(firstAuthor.getName(), "Paul Xavier"); + } + + @Test + public void givenAuthors_whenDescOrderingSltQry_thenWeGetOrderedAuthors() { + SelectQuery query = new SelectQuery(Author.class); + query.addOrdering(Author.NAME.desc()); + + List authors = query.select(context); + Author firstAuthor = authors.get(0); + + assertEquals(authors.size(), 3); + assertEquals(firstAuthor.getName(), "pAuL Smith"); + } + + @Test + public void givenAuthors_onContainsObjS_thenWeGetOneRecord() { + List authors = ObjectSelect.query(Author.class) + .where(Author.NAME.contains("Paul")) + .select(context); + + assertEquals(authors.size(), 1); + } + + @Test + public void givenAuthors_whenLikeObjS_thenWeGetTwoAuthors() { + List authors = ObjectSelect.query(Author.class) + .where(Author.NAME.likeIgnoreCase("Paul%")) + .select(context); + + assertEquals(authors.size(), 2); + } + + @Test + public void givenTwoAuthor_whenEndsWithObjS_thenWeGetOrderedAuthors() { + List authors = ObjectSelect.query(Author.class) + .where(Author.NAME.endsWith("Sarra")) + .select(context); + Author firstAuthor = authors.get(0); + + assertEquals(authors.size(), 1); + assertEquals(firstAuthor.getName(), "Vicky Sarra"); + } + + @Test + public void givenTwoAuthor_whenInObjS_thenWeGetAuthors() { + List names = Arrays.asList("Paul Xavier", "pAuL Smith", "Vicky Sarra"); + List authors = ObjectSelect.query(Author.class) + .where(Author.NAME.in(names)) + .select(context); + + assertEquals(authors.size(), 3); + } + + @Test + public void givenTwoAuthor_whenNinObjS_thenWeGetAuthors() { + List names = Arrays.asList("Paul Xavier", "pAuL Smith"); + List authors = ObjectSelect.query(Author.class) + .where(Author.NAME.nin(names)) + .select(context); + Author author = authors.get(0); + + assertEquals(authors.size(), 1); + assertEquals(author.getName(), "Vicky Sarra"); + } + + @Test + public void givenTwoAuthor_whenIsNotNullObjS_thenWeGetAuthors() { + List authors = ObjectSelect.query(Author.class) + .where(Author.NAME.isNotNull()) + .select(context); + + assertEquals(authors.size(), 3); + } + + @Test + public void givenAuthors_whenFindAllEJBQL_thenWeGetThreeAuthors() { + EJBQLQuery query = new EJBQLQuery("select a FROM Author a"); + List authors = context.performQuery(query); + + assertEquals(authors.size(), 3); + } + + @Test + public void givenAuthors_whenFindByNameEJBQL_thenWeGetOneAuthor() { + EJBQLQuery query = new EJBQLQuery("select a FROM Author a WHERE a.name = 'Vicky Sarra'"); + List authors = context.performQuery(query); + Author author = authors.get(0); + + assertEquals(authors.size(), 1); + assertEquals(author.getName(), "Vicky Sarra"); + } + + @Test + public void givenAuthors_whenUpdadingByNameEJBQL_thenWeGetTheUpdatedAuthor() { + EJBQLQuery query = new EJBQLQuery("UPDATE Author AS a SET a.name = 'Vicky Edison' WHERE a.name = 'Vicky Sarra'"); + QueryResponse queryResponse = context.performGenericQuery(query); + + EJBQLQuery queryUpdatedAuthor = new EJBQLQuery("select a FROM Author a WHERE a.name = 'Vicky Edison'"); + List authors = context.performQuery(queryUpdatedAuthor); + Author author = authors.get(0); + + assertNotNull(author); + } + + @Test + public void givenAuthors_whenSeletingNamesEJBQL_thenWeGetListWithSizeThree() { + String [] args = {"Paul Xavier", "pAuL Smith", "Vicky Sarra"}; + List names = Arrays.asList(args); + EJBQLQuery query = new EJBQLQuery("select a.name FROM Author a"); + List nameList = context.performQuery(query); + + Collections.sort(names); + Collections.sort(nameList); + + assertEquals(names.size(), 3); + assertEquals(nameList.size(), 3); + assertEquals(names, nameList); + } + + @Test + public void givenAuthors_whenDeletingAllWithEJB_thenWeGetNoAuthor() { + EJBQLQuery deleteQuery = new EJBQLQuery("delete FROM Author"); + EJBQLQuery findAllQuery = new EJBQLQuery("select a FROM Author a"); + + context.performQuery(deleteQuery); + List objects = context.performQuery(findAllQuery); + + assertEquals(objects.size(), 0); + } + + @Test + public void givenAuthors_whenInsertingSQLExec_thenWeGetNewAuthor() { + int inserted = SQLExec + .query("INSERT INTO Author (name) VALUES ('Baeldung')") + .update(context); + + assertEquals(inserted, 1); + } + + @Test + public void givenAuthors_whenUpdatingSQLExec_thenItsUpdated() { + int updated = SQLExec + .query("UPDATE Author SET name = 'Baeldung' WHERE name = 'Vicky Sarra'") + .update(context); + + assertEquals(updated, 1); + } +} diff --git a/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneOperationTests.java b/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneOperationTests.java new file mode 100644 index 0000000000..8a0d210d8d --- /dev/null +++ b/apache-cayenne/src/test/java/com/baeldung/apachecayenne/CayenneOperationTests.java @@ -0,0 +1,131 @@ +package com.baeldung.apachecayenne; + +import com.baeldung.apachecayenne.persistent.Article; +import com.baeldung.apachecayenne.persistent.Author; +import org.apache.cayenne.ObjectContext; +import org.apache.cayenne.configuration.server.ServerRuntime; +import org.apache.cayenne.query.ObjectSelect; +import org.apache.cayenne.query.SQLTemplate; +import org.junit.After; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; + +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertNull; + + +public class CayenneOperationTests { + private static ObjectContext context = null; + + @BeforeClass + public static void setupTheCayenneContext() { + ServerRuntime cayenneRuntime = ServerRuntime.builder() + .addConfig("cayenne-project.xml") + .build(); + context = cayenneRuntime.newContext(); + } + + @After + public void deleteAllRecords() { + SQLTemplate deleteArticles = new SQLTemplate(Article.class, "delete from article"); + SQLTemplate deleteAuthors = new SQLTemplate(Author.class, "delete from author"); + + context.performGenericQuery(deleteArticles); + context.performGenericQuery(deleteAuthors); + } + + @Test + public void givenAuthor_whenInsert_thenWeGetOneRecordInTheDatabase() { + Author author = context.newObject(Author.class); + author.setName("Paul"); + + context.commitChanges(); + + long records = ObjectSelect.dataRowQuery(Author.class).selectCount(context); + assertEquals(1, records); + } + + @Test + public void givenAuthor_whenInsert_andQueryByFirstName_thenWeGetTheAuthor() { + Author author = context.newObject(Author.class); + author.setName("Paul"); + + context.commitChanges(); + + Author expectedAuthor = ObjectSelect.query(Author.class) + .where(Author.NAME.eq("Paul")) + .selectOne(context); + + assertEquals("Paul", expectedAuthor.getName()); + } + + @Test + public void givenTwoAuthor_whenInsert_andQueryAll_thenWeGetTwoAuthors() { + Author firstAuthor = context.newObject(Author.class); + firstAuthor.setName("Paul"); + + Author secondAuthor = context.newObject(Author.class); + secondAuthor.setName("Ludovic"); + + context.commitChanges(); + + List authors = ObjectSelect.query(Author.class).select(context); + assertEquals(2, authors.size()); + } + + @Test + public void givenAuthor_whenUpdating_thenWeGetAnUpatedeAuthor() { + Author author = context.newObject(Author.class); + author.setName("Paul"); + context.commitChanges(); + + Author expectedAuthor = ObjectSelect.query(Author.class) + .where(Author.NAME.eq("Paul")) + .selectOne(context); + expectedAuthor.setName("Garcia"); + context.commitChanges(); + + assertEquals(author.getName(), expectedAuthor.getName()); + } + + @Test + public void givenAuthor_whenDeleting_thenWeLostHisDetails() { + Author author = context.newObject(Author.class); + author.setName("Paul"); + context.commitChanges(); + + Author savedAuthor = ObjectSelect.query(Author.class) + .where(Author.NAME.eq("Paul")).selectOne(context); + if(savedAuthor != null) { + context.deleteObjects(author); + context.commitChanges(); + } + + Author expectedAuthor = ObjectSelect.query(Author.class) + .where(Author.NAME.eq("Paul")).selectOne(context); + assertNull(expectedAuthor); + } + + @Test + public void givenAuthor_whenAttachingToArticle_thenTheRelationIsMade() { + Author author = context.newObject(Author.class); + author.setName("Paul"); + + Article article = context.newObject(Article.class); + article.setTitle("My post title"); + article.setContent("The content"); + article.setAuthor(author); + + context.commitChanges(); + + Author expectedAuthor = ObjectSelect.query(Author.class) + .where(Author.NAME.eq("Paul")) + .selectOne(context); + + Article expectedArticle = (expectedAuthor.getArticles()).get(0); + assertEquals(article.getTitle(), expectedArticle.getTitle()); + } + +} diff --git a/apache-cxf/README.md b/apache-cxf/README.md index d8f1912070..1e66ce5da8 100644 --- a/apache-cxf/README.md +++ b/apache-cxf/README.md @@ -1,2 +1,5 @@ ## Relevant Articles: - [Introduction to Apache CXF Aegis Data Binding](http://www.baeldung.com/aegis-data-binding-in-apache-cxf) +- [Apache CXF Support for RESTful Web Services](http://www.baeldung.com/apache-cxf-rest-api) +- [A Guide to Apache CXF with Spring](http://www.baeldung.com/apache-cxf-with-spring) +- [Introduction to Apache CXF](http://www.baeldung.com/introduction-to-apache-cxf) diff --git a/apache-poi/src/main/java/com/baeldung/poi/powerpoint/PowerPointHelper.java b/apache-poi/src/main/java/com/baeldung/poi/powerpoint/PowerPointHelper.java new file mode 100644 index 0000000000..e2af4f8808 --- /dev/null +++ b/apache-poi/src/main/java/com/baeldung/poi/powerpoint/PowerPointHelper.java @@ -0,0 +1,224 @@ +package com.baeldung.poi.powerpoint; + +import org.apache.poi.sl.usermodel.AutoNumberingScheme; +import org.apache.poi.sl.usermodel.PictureData; +import org.apache.poi.sl.usermodel.TableCell; +import org.apache.poi.sl.usermodel.TextParagraph; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xslf.usermodel.*; + +import java.awt.*; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Helper class for the PowerPoint presentation creation + */ +public class PowerPointHelper { + + /** + * Read an existing presentation + * + * @param fileLocation + * File location of the presentation + * @return instance of {@link XMLSlideShow} + * @throws IOException + */ + public XMLSlideShow readingExistingSlideShow(String fileLocation) throws IOException { + return new XMLSlideShow(new FileInputStream(fileLocation)); + } + + /** + * Create a sample presentation + * + * @param fileLocation + * File location of the presentation + * @throws IOException + */ + public void createPresentation(String fileLocation) throws IOException { + // Create presentation + XMLSlideShow ppt = new XMLSlideShow(); + + XSLFSlideMaster defaultMaster = ppt.getSlideMasters().get(0); + + // Retriving the slide layout + XSLFSlideLayout layout = defaultMaster.getLayout(SlideLayout.TITLE_ONLY); + + // Creating the 1st slide + XSLFSlide slide1 = ppt.createSlide(layout); + XSLFTextShape title = slide1.getPlaceholder(0); + // Clearing text to remove the predefined one in the template + title.clearText(); + XSLFTextParagraph p = title.addNewTextParagraph(); + + XSLFTextRun r1 = p.addNewTextRun(); + r1.setText("Baeldung"); + r1.setFontColor(new Color(78, 147, 89)); + r1.setFontSize(48.); + + // Add Image + ClassLoader classLoader = getClass().getClassLoader(); + byte[] pictureData = IOUtils.toByteArray(new FileInputStream(classLoader.getResource("logo-leaf.png").getFile())); + + XSLFPictureData pd = ppt.addPicture(pictureData, PictureData.PictureType.PNG); + XSLFPictureShape picture = slide1.createPicture(pd); + picture.setAnchor(new Rectangle(320, 230, 100, 92)); + + // Creating 2nd slide + layout = defaultMaster.getLayout(SlideLayout.TITLE_AND_CONTENT); + XSLFSlide slide2 = ppt.createSlide(layout); + + // setting the tile + title = slide2.getPlaceholder(0); + title.clearText(); + XSLFTextRun r = title.addNewTextParagraph().addNewTextRun(); + r.setText("Baeldung"); + + // Adding the link + XSLFHyperlink link = r.createHyperlink(); + link.setAddress("http://www.baeldung.com"); + + // setting the content + XSLFTextShape content = slide2.getPlaceholder(1); + content.clearText(); // unset any existing text + content.addNewTextParagraph().addNewTextRun().setText("First paragraph"); + content.addNewTextParagraph().addNewTextRun().setText("Second paragraph"); + content.addNewTextParagraph().addNewTextRun().setText("Third paragraph"); + + // Creating 3rd slide - List + layout = defaultMaster.getLayout(SlideLayout.TITLE_AND_CONTENT); + XSLFSlide slide3 = ppt.createSlide(layout); + title = slide3.getPlaceholder(0); + title.clearText(); + r = title.addNewTextParagraph().addNewTextRun(); + r.setText("Lists"); + + content = slide3.getPlaceholder(1); + content.clearText(); + XSLFTextParagraph p1 = content.addNewTextParagraph(); + p1.setIndentLevel(0); + p1.setBullet(true); + r1 = p1.addNewTextRun(); + r1.setText("Bullet"); + + // the next three paragraphs form an auto-numbered list + XSLFTextParagraph p2 = content.addNewTextParagraph(); + p2.setBulletAutoNumber(AutoNumberingScheme.alphaLcParenRight, 1); + p2.setIndentLevel(1); + XSLFTextRun r2 = p2.addNewTextRun(); + r2.setText("Numbered List Item - 1"); + + // Creating 4th slide + XSLFSlide slide4 = ppt.createSlide(); + createTable(slide4); + + // Save presentation + FileOutputStream out = new FileOutputStream(fileLocation); + ppt.write(out); + out.close(); + + // Closing presentation + ppt.close(); + } + + /** + * Delete a slide from the presentation + * + * @param ppt + * The presentation + * @param slideNumber + * The number of the slide to be deleted (0-based) + */ + public void deleteSlide(XMLSlideShow ppt, int slideNumber) { + ppt.removeSlide(slideNumber); + } + + /** + * Re-order the slides inside a presentation + * + * @param ppt + * The presentation + * @param slideNumber + * The number of the slide to move + * @param newSlideNumber + * The new position of the slide (0-base) + */ + public void reorderSlide(XMLSlideShow ppt, int slideNumber, int newSlideNumber) { + List slides = ppt.getSlides(); + + XSLFSlide secondSlide = slides.get(slideNumber); + ppt.setSlideOrder(secondSlide, newSlideNumber); + } + + /** + * Retrieve the placeholder inside a slide + * + * @param slide + * The slide + * @return List of placeholder inside a slide + */ + public List retrieveTemplatePlaceholders(XSLFSlide slide) { + List placeholders = new ArrayList<>(); + + for (XSLFShape shape : slide.getShapes()) { + if (shape instanceof XSLFAutoShape) { + placeholders.add(shape); + } + } + return placeholders; + } + + /** + * Create a table + * + * @param slide + * Slide + */ + private void createTable(XSLFSlide slide) { + + XSLFTable tbl = slide.createTable(); + tbl.setAnchor(new Rectangle(50, 50, 450, 300)); + + int numColumns = 3; + int numRows = 5; + + // header + XSLFTableRow headerRow = tbl.addRow(); + headerRow.setHeight(50); + for (int i = 0; i < numColumns; i++) { + XSLFTableCell th = headerRow.addCell(); + XSLFTextParagraph p = th.addNewTextParagraph(); + p.setTextAlign(TextParagraph.TextAlign.CENTER); + XSLFTextRun r = p.addNewTextRun(); + r.setText("Header " + (i + 1)); + r.setBold(true); + r.setFontColor(Color.white); + th.setFillColor(new Color(79, 129, 189)); + th.setBorderWidth(TableCell.BorderEdge.bottom, 2.0); + th.setBorderColor(TableCell.BorderEdge.bottom, Color.white); + // all columns are equally sized + tbl.setColumnWidth(i, 150); + } + + // data + for (int rownum = 0; rownum < numRows; rownum++) { + XSLFTableRow tr = tbl.addRow(); + tr.setHeight(50); + for (int i = 0; i < numColumns; i++) { + XSLFTableCell cell = tr.addCell(); + XSLFTextParagraph p = cell.addNewTextParagraph(); + XSLFTextRun r = p.addNewTextRun(); + + r.setText("Cell " + (i * rownum + 1)); + if (rownum % 2 == 0) { + cell.setFillColor(new Color(208, 216, 232)); + } else { + cell.setFillColor(new Color(233, 247, 244)); + } + } + } + } +} diff --git a/apache-poi/src/test/java/com/baeldung/poi/powerpoint/PowerPointIntegrationTest.java b/apache-poi/src/test/java/com/baeldung/poi/powerpoint/PowerPointIntegrationTest.java new file mode 100644 index 0000000000..5319208e85 --- /dev/null +++ b/apache-poi/src/test/java/com/baeldung/poi/powerpoint/PowerPointIntegrationTest.java @@ -0,0 +1,77 @@ +package com.baeldung.poi.powerpoint; + +import org.apache.poi.xslf.usermodel.XMLSlideShow; +import org.apache.poi.xslf.usermodel.XSLFShape; +import org.apache.poi.xslf.usermodel.XSLFSlide; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.List; + +public class PowerPointIntegrationTest { + + private PowerPointHelper pph; + private String fileLocation; + private static final String FILE_NAME = "presentation.pptx"; + + @Before + public void setUp() throws Exception { + File currDir = new File("."); + String path = currDir.getAbsolutePath(); + fileLocation = path.substring(0, path.length() - 1) + FILE_NAME; + + pph = new PowerPointHelper(); + pph.createPresentation(fileLocation); + } + + @Test + public void whenReadingAPresentation_thenOK() throws Exception { + XMLSlideShow xmlSlideShow = pph.readingExistingSlideShow(fileLocation); + + Assert.assertNotNull(xmlSlideShow); + Assert.assertEquals(4, xmlSlideShow.getSlides().size()); + } + + @Test + public void whenRetrievingThePlaceholdersForEachSlide_thenOK() throws Exception { + XMLSlideShow xmlSlideShow = pph.readingExistingSlideShow(fileLocation); + + List onlyTitleSlidePlaceholders = pph.retrieveTemplatePlaceholders(xmlSlideShow.getSlides().get(0)); + List titleAndBodySlidePlaceholders = pph.retrieveTemplatePlaceholders(xmlSlideShow.getSlides().get(1)); + List emptySlidePlaceholdes = pph.retrieveTemplatePlaceholders(xmlSlideShow.getSlides().get(3)); + + Assert.assertEquals(1, onlyTitleSlidePlaceholders.size()); + Assert.assertEquals(2, titleAndBodySlidePlaceholders.size()); + Assert.assertEquals(0, emptySlidePlaceholdes.size()); + + } + + @Test + public void whenSortingSlides_thenOK() throws Exception { + XMLSlideShow xmlSlideShow = pph.readingExistingSlideShow(fileLocation); + XSLFSlide slide4 = xmlSlideShow.getSlides().get(3); + pph.reorderSlide(xmlSlideShow, 3, 1); + + Assert.assertEquals(slide4, xmlSlideShow.getSlides().get(1)); + } + + @Test + public void givenPresentation_whenDeletingASlide_thenOK() throws Exception { + XMLSlideShow xmlSlideShow = pph.readingExistingSlideShow(fileLocation); + pph.deleteSlide(xmlSlideShow, 3); + + Assert.assertEquals(3, xmlSlideShow.getSlides().size()); + } + + @After + public void tearDown() throws Exception { + File testFile = new File(fileLocation); + if (testFile.exists()) { + testFile.delete(); + } + pph = null; + } +} diff --git a/apache-shiro/README.md b/apache-shiro/README.md index e69de29bb2..bc3480b266 100644 --- a/apache-shiro/README.md +++ b/apache-shiro/README.md @@ -0,0 +1,2 @@ +### Relevant articles +- [Introduction to Apache Shiro](http://www.baeldung.com/apache-shiro) diff --git a/apache-spark/README.md b/apache-spark/README.md new file mode 100644 index 0000000000..fb8059eb27 --- /dev/null +++ b/apache-spark/README.md @@ -0,0 +1,3 @@ +### Relevant articles + +- [Introduction to Apache Spark](http://www.baeldung.com/apache-spark) diff --git a/apache-spark/pom.xml b/apache-spark/pom.xml new file mode 100644 index 0000000000..1f95150ee7 --- /dev/null +++ b/apache-spark/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + + com.baeldung + apache-spark + 1.0-SNAPSHOT + jar + + apache-spark + http://maven.apache.org + + + UTF-8 + + + + + + org.apache.spark + spark-core_2.10 + 2.2.0 + + + junit + junit + 3.8.1 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + + + + + diff --git a/apache-spark/src/main/java/com/baeldung/WordCount.java b/apache-spark/src/main/java/com/baeldung/WordCount.java new file mode 100644 index 0000000000..bc73b05536 --- /dev/null +++ b/apache-spark/src/main/java/com/baeldung/WordCount.java @@ -0,0 +1,40 @@ +package com.baeldung; + +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +import org.apache.spark.SparkConf; +import org.apache.spark.api.java.JavaPairRDD; +import org.apache.spark.api.java.JavaRDD; +import org.apache.spark.api.java.JavaSparkContext; +import org.apache.spark.api.java.function.*; +import org.apache.spark.api.java.function.Function2; +import org.apache.spark.api.java.function.PairFunction; + +import scala.Tuple2; + +public class WordCount { + + private static final Pattern SPACE = Pattern.compile(" "); + + public static void main(String[] args) throws Exception { + if (args.length < 1) { + System.err.println("Usage: JavaWordCount "); + System.exit(1); + } + SparkConf sparkConf = new SparkConf().setAppName("JavaWordCount") + .setMaster("local"); + JavaSparkContext ctx = new JavaSparkContext(sparkConf); + JavaRDD lines = ctx.textFile(args[0], 1); + + JavaRDD words = lines.flatMap(s -> Arrays.asList(SPACE.split(s)).iterator()); + JavaPairRDD wordAsTuple = words.mapToPair(word -> new Tuple2<>(word, 1)); + JavaPairRDD wordWithCount = wordAsTuple.reduceByKey((Integer i1, Integer i2)->i1 + i2); + List> output = wordWithCount.collect(); + for (Tuple2 tuple : output) { + System.out.println(tuple._1() + ": " + tuple._2()); + } + ctx.stop(); + } +} diff --git a/apache-spark/src/main/resources/spark_example.txt b/apache-spark/src/main/resources/spark_example.txt new file mode 100644 index 0000000000..10fd71dc31 --- /dev/null +++ b/apache-spark/src/main/resources/spark_example.txt @@ -0,0 +1,3 @@ +Hello from Baeldung +Keep Learning Spark +Bye from Baeldung \ No newline at end of file diff --git a/asm/README.md b/asm/README.md new file mode 100644 index 0000000000..50d9c34324 --- /dev/null +++ b/asm/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [A Guide to Java Bytecode Manipulation with ASM](http://www.baeldung.com/java-asm) diff --git a/asm/pom.xml b/asm/pom.xml new file mode 100644 index 0000000000..407ceab458 --- /dev/null +++ b/asm/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + com.baeldung.examples + asm + 1.0 + jar + + + org.ow2.asm + asm + 5.2 + + + org.ow2.asm + asm-util + 5.2 + + + + UTF-8 + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + + com.baeldung.examples.asm.instrumentation.Premain + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.9 + + -javaagent:"C:\asm-1.0.jar" + + + + + \ No newline at end of file diff --git a/asm/src/main/java/com/baeldung/examples/asm/CustomClassWriter.java b/asm/src/main/java/com/baeldung/examples/asm/CustomClassWriter.java new file mode 100644 index 0000000000..d41a1a16a3 --- /dev/null +++ b/asm/src/main/java/com/baeldung/examples/asm/CustomClassWriter.java @@ -0,0 +1,160 @@ +package com.baeldung.examples.asm; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; +import static org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static org.objectweb.asm.Opcodes.ACC_STATIC; +import static org.objectweb.asm.Opcodes.ASM4; +import static org.objectweb.asm.Opcodes.V1_5; +import org.objectweb.asm.Type; +import org.objectweb.asm.util.TraceClassVisitor; + +/** + * + * @author baeldung + * @param + */ +public class CustomClassWriter { + + ClassReader reader; + ClassWriter writer; + AddFieldAdapter addFieldAdapter; + AddInterfaceAdapter addInterfaceAdapter; + PublicizeMethodAdapter pubMethAdapter; + final static String CLASSNAME = "java.lang.Integer"; + final static String CLONEABLE = "java/lang/Cloneable"; + + public CustomClassWriter() { + + try { + reader = new ClassReader(CLASSNAME); + writer = new ClassWriter(reader, 0); + + } catch (IOException ex) { + Logger.getLogger(CustomClassWriter.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public CustomClassWriter(byte[] contents) { + reader = new ClassReader(contents); + writer = new ClassWriter(reader, 0); + } + + public static void main(String[] args) { + CustomClassWriter ccw = new CustomClassWriter(); + ccw.publicizeMethod(); + } + + public byte[] addField() { + addFieldAdapter = new AddFieldAdapter("aNewBooleanField", org.objectweb.asm.Opcodes.ACC_PUBLIC, writer); + reader.accept(addFieldAdapter, 0); + return writer.toByteArray(); + } + + public byte[] publicizeMethod() { + pubMethAdapter = new PublicizeMethodAdapter(writer); + reader.accept(pubMethAdapter, 0); + return writer.toByteArray(); + } + + public byte[] addInterface() { + addInterfaceAdapter = new AddInterfaceAdapter(writer); + reader.accept(addInterfaceAdapter, 0); + return writer.toByteArray(); + } + + public class AddInterfaceAdapter extends ClassVisitor { + + public AddInterfaceAdapter(ClassVisitor cv) { + super(ASM4, cv); + } + + @Override + public void visit(int version, int access, String name, + String signature, String superName, String[] interfaces) { + String[] holding = new String[interfaces.length + 1]; + holding[holding.length - 1] = CLONEABLE; + System.arraycopy(interfaces, 0, holding, 0, interfaces.length); + + cv.visit(V1_5, access, name, signature, superName, holding); + } + + } + + public class PublicizeMethodAdapter extends ClassVisitor { + + final Logger logger = Logger.getLogger("PublicizeMethodAdapter"); + TraceClassVisitor tracer; + PrintWriter pw = new PrintWriter(System.out); + + public PublicizeMethodAdapter(ClassVisitor cv) { + super(ASM4, cv); + this.cv = cv; + tracer = new TraceClassVisitor(cv, pw); + } + + @Override + public MethodVisitor visitMethod(int access, + String name, + String desc, + String signature, + String[] exceptions) { + + if (name.equals("toUnsignedString0")) { + logger.info("Visiting unsigned method"); + return tracer.visitMethod(ACC_PUBLIC + ACC_STATIC, name, desc, signature, exceptions); + } + return tracer.visitMethod(access, name, desc, signature, exceptions); + + } + + public void visitEnd() { + tracer.visitEnd(); + System.out.println(tracer.p.getText()); + } + + } + + public class AddFieldAdapter extends ClassVisitor { + + String fieldName; + int access; + boolean isFieldPresent; + + public AddFieldAdapter(String fieldName, int access, ClassVisitor cv) { + super(ASM4, cv); + this.cv = cv; + this.access = access; + this.fieldName = fieldName; + } + + @Override + public FieldVisitor visitField(int access, String name, String desc, + String signature, Object value) { + if (name.equals(fieldName)) { + isFieldPresent = true; + } + return cv.visitField(access, name, desc, signature, value); + } + + @Override + public void visitEnd() { + if (!isFieldPresent) { + FieldVisitor fv = cv.visitField(access, fieldName, Type.BOOLEAN_TYPE.toString(), null, null); + if (fv != null) { + fv.visitEnd(); + } + } + cv.visitEnd(); + } + + } + +} diff --git a/asm/src/main/java/com/baeldung/examples/asm/instrumentation/Premain.java b/asm/src/main/java/com/baeldung/examples/asm/instrumentation/Premain.java new file mode 100644 index 0000000000..a3e69b6785 --- /dev/null +++ b/asm/src/main/java/com/baeldung/examples/asm/instrumentation/Premain.java @@ -0,0 +1,32 @@ +package com.baeldung.examples.asm.instrumentation; + +import com.baeldung.examples.asm.CustomClassWriter; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.instrument.Instrumentation; +import java.security.ProtectionDomain; + +/** + * + * @author baeldung + */ +public class Premain { + + public static void premain(String agentArgs, Instrumentation inst) { + inst.addTransformer(new ClassFileTransformer() { + + @Override + public byte[] transform(ClassLoader l, String name, Class c, + ProtectionDomain d, byte[] b) + throws IllegalClassFormatException { + + if (name.equals("java/lang/Integer")) { + CustomClassWriter cr = new CustomClassWriter(b); + return cr.addField(); + } + return b; + } + }); + } + +} diff --git a/atomix/.gitignore b/atomix/.gitignore new file mode 100644 index 0000000000..ea8c4bf7f3 --- /dev/null +++ b/atomix/.gitignore @@ -0,0 +1 @@ +/target diff --git a/atomix/README.md b/atomix/README.md new file mode 100644 index 0000000000..fb22eec8dc --- /dev/null +++ b/atomix/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Introduction to Atomix](http://www.baeldung.com/atomix) diff --git a/atomix/pom.xml b/atomix/pom.xml new file mode 100644 index 0000000000..80c573dd86 --- /dev/null +++ b/atomix/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + com.atomix.io + atomix + 0.0.1-SNAPSHOT + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + io.atomix + atomix-all + 1.0.0-rc9 + + + junit + junit + 4.9 + test + + + log4j + log4j + 1.2.17 + + + + + + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + + + + + + + diff --git a/atomix/src/main/java/com/atomix/example/BootstrapingCluster.java b/atomix/src/main/java/com/atomix/example/BootstrapingCluster.java new file mode 100644 index 0000000000..6c5c94d307 --- /dev/null +++ b/atomix/src/main/java/com/atomix/example/BootstrapingCluster.java @@ -0,0 +1,27 @@ +package com.atomix.example; + +import io.atomix.AtomixReplica; +import io.atomix.catalyst.transport.Address; +import io.atomix.catalyst.transport.netty.NettyTransport; +import io.atomix.copycat.server.storage.Storage; +import io.atomix.copycat.server.storage.StorageLevel; + +import java.io.File; +import java.util.concurrent.CompletableFuture; + +public class BootstrapingCluster { + + public static void main(String[] args) { + Storage storage = Storage.builder() + .withDirectory(new File("log")) + .withStorageLevel(StorageLevel.DISK) + .build(); + AtomixReplica replica = AtomixReplica.builder(new Address("localhost", 8700)) + .withStorage(storage) + .withTransport(new NettyTransport()) + .build(); + + CompletableFuture completableFuture = replica.bootstrap(); + completableFuture.join(); + } +} diff --git a/atomix/src/main/java/com/atomix/example/OtherNodes.java b/atomix/src/main/java/com/atomix/example/OtherNodes.java new file mode 100644 index 0000000000..e5688b062f --- /dev/null +++ b/atomix/src/main/java/com/atomix/example/OtherNodes.java @@ -0,0 +1,71 @@ +package com.atomix.example; + +import io.atomix.AtomixReplica; +import io.atomix.catalyst.transport.Address; +import io.atomix.catalyst.transport.netty.NettyTransport; +import io.atomix.concurrent.DistributedLock; +import io.atomix.copycat.server.storage.Storage; +import io.atomix.copycat.server.storage.StorageLevel; + +import java.io.File; +import java.util.Arrays; +import java.util.List; + +public class OtherNodes { + + public static void main(String[] args) throws InterruptedException { + List
    cluster = Arrays + .asList( + new Address("localhost", 8700), + new Address("localhost", 8701), + new Address("localhost", 8702)); + + Storage storage = Storage.builder() + .withDirectory(new File("log")) + .withStorageLevel(StorageLevel.DISK) + .build(); + + AtomixReplica replica2 = AtomixReplica.builder(new Address("localhost", 8701)) + .withStorage(storage) + .withTransport(new NettyTransport()) + .build(); + + WorkerThread WT1 = new WorkerThread(replica2, cluster); + WT1.run(); + + AtomixReplica replica3 = AtomixReplica.builder(new Address("localhost", 8702)) + .withStorage(storage) + .withTransport(new NettyTransport()) + .build(); + + WorkerThread WT2 = new WorkerThread(replica3, cluster); + WT2.run(); + + Thread.sleep(6000); + + DistributedLock lock = replica2.getLock("my-lock") + .join(); + lock.lock() + .thenRun(() -> System.out.println("Acquired a lock")); + + replica2.getMap("map") + .thenCompose(m -> m.put("bar", "Hello world!")) + .thenRun(() -> System.out.println("Value is set in Distributed Map")) + .join(); + } + + private static class WorkerThread extends Thread { + private AtomixReplica replica; + private List
    cluster; + + WorkerThread(AtomixReplica replica, List
    cluster) { + this.replica = replica; + this.cluster = cluster; + } + + public void run() { + replica.join(cluster) + .join(); + } + } +} \ No newline at end of file diff --git a/atomix/src/test/java/com/atomix/exampletest/AtomixClientLiveTest.java b/atomix/src/test/java/com/atomix/exampletest/AtomixClientLiveTest.java new file mode 100644 index 0000000000..9268a4a69b --- /dev/null +++ b/atomix/src/test/java/com/atomix/exampletest/AtomixClientLiveTest.java @@ -0,0 +1,35 @@ +package com.atomix.exampletest; + +import io.atomix.AtomixClient; +import io.atomix.catalyst.transport.Address; +import io.atomix.catalyst.transport.netty.NettyTransport; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import static org.junit.Assert.assertEquals; + +public class AtomixClientLiveTest { + + private final AtomixClient client = AtomixClient.builder() + .withTransport(new NettyTransport()) + .build(); + + @Test + public void whenBootstrap_thenShouldGet() throws InterruptedException, ExecutionException { + List
    cluster = Arrays.asList( + new Address("localhost", 8700), + new Address("localhsot", 8701)); + + String value = client.connect(cluster) + .thenRun(() -> System.out.println("Client Connected")) + .thenCompose(c -> client.getMap("map")) + .thenCompose(m -> m.get("bar")) + .thenApply(a -> (String) a) + .get(); + + assertEquals("Hello world!", value); + } +} diff --git a/aws/README.md b/aws/README.md index 10db004765..b6d0b79d91 100644 --- a/aws/README.md +++ b/aws/README.md @@ -1,3 +1,6 @@ ### Relevant articles - [AWS Lambda Using DynamoDB With Java](http://www.baeldung.com/aws-lambda-dynamodb-java) +- [AWS S3 with Java](http://www.baeldung.com/aws-s3-java) +- [AWS Lambda With Java](http://www.baeldung.com/java-aws-lambda) + diff --git a/bootique/README.md b/bootique/README.md new file mode 100644 index 0000000000..2ef898fcf7 --- /dev/null +++ b/bootique/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to Bootique](http://www.baeldung.com/bootique) diff --git a/bootique/dependency-reduced-pom.xml b/bootique/dependency-reduced-pom.xml index ed18f4e42a..ab09cfb7b1 100644 --- a/bootique/dependency-reduced-pom.xml +++ b/bootique/dependency-reduced-pom.xml @@ -28,8 +28,14 @@ junit junit - 3.8.1 + 4.12 test + + + hamcrest-core + org.hamcrest + + diff --git a/camel-api/README.md b/camel-api/README.md index fe8dadcfe1..0e85db4a7f 100644 --- a/camel-api/README.md +++ b/camel-api/README.md @@ -13,3 +13,7 @@ and a BODY Payload like {"id": 1,"name": "World"} and we will get a return code of 201 and the response: Hello, World - if the transform() method from Application class is uncommented and the process() method is commented or return code of 201 and the response: {"id": 10,"name": "Hello, World"} - if the transform() method from Application class is commented and the process() method is uncommented + +## Relevant articles: + +- [Apache Camel with Spring Boot](http://www.baeldung.com/apache-camel-spring-boot) diff --git a/cas/cas-secured-app/.gitignore b/cas/cas-secured-app/.gitignore new file mode 100644 index 0000000000..cd4878159f --- /dev/null +++ b/cas/cas-secured-app/.gitignore @@ -0,0 +1,27 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ +/.mvn/ +/mvnw +/mvnw.cmd \ No newline at end of file diff --git a/cas/cas-secured-app/pom.xml b/cas/cas-secured-app/pom.xml new file mode 100644 index 0000000000..543354e8b3 --- /dev/null +++ b/cas/cas-secured-app/pom.xml @@ -0,0 +1,129 @@ + + + 4.0.0 + + com.baeldung + cas-secured-app + 0.0.1-SNAPSHOT + jar + + cas-secured-app + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.BUILD-SNAPSHOT + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security + spring-security-cas + + + org.springframework.boot + spring-boot-starter-freemarker + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-devtools + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + diff --git a/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredAppApplication.java b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredAppApplication.java new file mode 100644 index 0000000000..25cbb9bc9b --- /dev/null +++ b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/CasSecuredAppApplication.java @@ -0,0 +1,91 @@ +package com.baeldung.cassecuredapp; + +import org.jasig.cas.client.session.SingleSignOutFilter; +import org.jasig.cas.client.session.SingleSignOutHttpSessionListener; +import org.jasig.cas.client.validation.Cas30ServiceTicketValidator; +import org.jasig.cas.client.validation.TicketValidator; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.context.event.EventListener; +import org.springframework.security.cas.ServiceProperties; +import org.springframework.security.cas.authentication.CasAuthenticationProvider; +import org.springframework.security.cas.web.CasAuthenticationEntryPoint; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.logout.LogoutFilter; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; + +import javax.servlet.http.HttpSessionEvent; + +@SpringBootApplication +public class CasSecuredAppApplication { + + public static void main(String[] args) { + SpringApplication.run(CasSecuredAppApplication.class, args); + } + + @Bean + public ServiceProperties serviceProperties() { + ServiceProperties serviceProperties = new ServiceProperties(); + serviceProperties.setService("http://localhost:9000/login/cas"); + serviceProperties.setSendRenew(false); + return serviceProperties; + } + + @Bean + @Primary + public AuthenticationEntryPoint authenticationEntryPoint(ServiceProperties sP) { + CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint(); + entryPoint.setLoginUrl("https://localhost:6443/cas/login"); + entryPoint.setServiceProperties(sP); + return entryPoint; + } + + @Bean + public TicketValidator ticketValidator() { + return new Cas30ServiceTicketValidator("https://localhost:6443/cas"); + } + + @Bean + public CasAuthenticationProvider casAuthenticationProvider() { + CasAuthenticationProvider provider = new CasAuthenticationProvider(); + provider.setServiceProperties(serviceProperties()); + provider.setTicketValidator(ticketValidator()); + provider.setUserDetailsService((s) -> new User("test@test.com", "smatt", + true, true, true, true, + AuthorityUtils.createAuthorityList("ROLE_ADMIN"))); + provider.setKey("CAS_PROVIDER_LOCALHOST_9000"); + return provider; + } + + + @Bean + public SecurityContextLogoutHandler securityContextLogoutHandler() { + return new SecurityContextLogoutHandler(); + } + + @Bean + public LogoutFilter logoutFilter() { + LogoutFilter logoutFilter = new LogoutFilter( + "https://localhost:6443/cas/logout", securityContextLogoutHandler()); + logoutFilter.setFilterProcessesUrl("/logout/cas"); + return logoutFilter; + } + + @Bean + public SingleSignOutFilter singleSignOutFilter() { + SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter(); + singleSignOutFilter.setCasServerUrlPrefix("https://localhost:6443/cas"); + singleSignOutFilter.setIgnoreInitConfiguration(true); + return singleSignOutFilter; + } + + @EventListener + public SingleSignOutHttpSessionListener singleSignOutHttpSessionListener(HttpSessionEvent event) { + return new SingleSignOutHttpSessionListener(); + } +} diff --git a/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/config/SecurityConfig.java b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/config/SecurityConfig.java new file mode 100644 index 0000000000..2eabed49e1 --- /dev/null +++ b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/config/SecurityConfig.java @@ -0,0 +1,83 @@ +package com.baeldung.cassecuredapp.config; + +import org.jasig.cas.client.session.SingleSignOutFilter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.cas.ServiceProperties; +import org.springframework.security.cas.authentication.CasAuthenticationProvider; +import org.springframework.security.cas.web.CasAuthenticationFilter; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.logout.LogoutFilter; + +import java.util.Arrays; + +@EnableWebSecurity +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + private AuthenticationProvider authenticationProvider; + private AuthenticationEntryPoint authenticationEntryPoint; + private SingleSignOutFilter singleSignOutFilter; + private LogoutFilter logoutFilter; + + @Autowired + public SecurityConfig(CasAuthenticationProvider casAuthenticationProvider, AuthenticationEntryPoint eP, + LogoutFilter lF + , SingleSignOutFilter ssF + ) { + this.authenticationProvider = casAuthenticationProvider; + this.authenticationEntryPoint = eP; + + this.logoutFilter = lF; + this.singleSignOutFilter = ssF; + + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .regexMatchers("/secured.*", "/login") + .authenticated() + .and() + .authorizeRequests() + .regexMatchers("/") + .permitAll() + .and() + .httpBasic() + .authenticationEntryPoint(authenticationEntryPoint) + .and() + .logout().logoutSuccessUrl("/logout") + .and() + .addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class) + .addFilterBefore(logoutFilter, LogoutFilter.class); + + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(authenticationProvider); + } + + @Override + protected AuthenticationManager authenticationManager() throws Exception { + return new ProviderManager(Arrays.asList(authenticationProvider)); + } + + @Bean + public CasAuthenticationFilter casAuthenticationFilter(ServiceProperties sP) throws Exception { + CasAuthenticationFilter filter = new CasAuthenticationFilter(); + filter.setServiceProperties(sP); + filter.setAuthenticationManager(authenticationManager()); + return filter; + } + +} diff --git a/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/AuthController.java b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/AuthController.java new file mode 100644 index 0000000000..7faccbb125 --- /dev/null +++ b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/AuthController.java @@ -0,0 +1,36 @@ +package com.baeldung.cassecuredapp.controllers; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler; +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; +import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Controller +public class AuthController { + + private Logger logger = LogManager.getLogger(AuthController.class); + + @GetMapping("/logout") + public String logout( + HttpServletRequest request, HttpServletResponse response, SecurityContextLogoutHandler logoutHandler) { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + logoutHandler.logout(request, response, auth ); + new CookieClearingLogoutHandler(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY).logout(request, response, auth); + return "auth/logout"; + } + + + @GetMapping("/login") + public String login() { + return "redirect:/secured"; + } + +} diff --git a/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/IndexController.java b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/IndexController.java new file mode 100644 index 0000000000..75956cf493 --- /dev/null +++ b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/IndexController.java @@ -0,0 +1,15 @@ +package com.baeldung.cassecuredapp.controllers; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + + +@Controller +public class IndexController { + + @GetMapping("/") + public String index() { + return "index"; + } +} diff --git a/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/SecuredPageController.java b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/SecuredPageController.java new file mode 100644 index 0000000000..9a872d1f40 --- /dev/null +++ b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/SecuredPageController.java @@ -0,0 +1,24 @@ +package com.baeldung.cassecuredapp.controllers; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping(value = "/secured") +public class SecuredPageController { + + @GetMapping + public String index(ModelMap modelMap) { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if( auth != null && auth.getPrincipal() != null + && auth.getPrincipal() instanceof UserDetails) { + modelMap.put("username", ((UserDetails) auth.getPrincipal()).getUsername()); + } + return "secure/index"; + } +} diff --git a/cas/cas-secured-app/src/main/resources/application.properties b/cas/cas-secured-app/src/main/resources/application.properties new file mode 100644 index 0000000000..99802c632f --- /dev/null +++ b/cas/cas-secured-app/src/main/resources/application.properties @@ -0,0 +1 @@ +server.port=9000 \ No newline at end of file diff --git a/cas/cas-secured-app/src/main/resources/templates/auth/logout.ftl b/cas/cas-secured-app/src/main/resources/templates/auth/logout.ftl new file mode 100644 index 0000000000..eac345ec33 --- /dev/null +++ b/cas/cas-secured-app/src/main/resources/templates/auth/logout.ftl @@ -0,0 +1,10 @@ + + + Cas Secured App - Logout + + +

    You have logged out of Cas Secured Spring Boot App Successfully

    +
    +Log out of all other Services + + \ No newline at end of file diff --git a/cas/cas-secured-app/src/main/resources/templates/index.ftl b/cas/cas-secured-app/src/main/resources/templates/index.ftl new file mode 100644 index 0000000000..d407756044 --- /dev/null +++ b/cas/cas-secured-app/src/main/resources/templates/index.ftl @@ -0,0 +1,11 @@ + + + Cas Secured App - Index + + +

    Welcome to Cas Secured Spring Boot App

    +

    This is a Public Page

    +
    +Login + + \ No newline at end of file diff --git a/cas/cas-secured-app/src/main/resources/templates/secure/index.ftl b/cas/cas-secured-app/src/main/resources/templates/secure/index.ftl new file mode 100644 index 0000000000..210ebecc7b --- /dev/null +++ b/cas/cas-secured-app/src/main/resources/templates/secure/index.ftl @@ -0,0 +1,12 @@ + + + Cas Secured App - Secured + + +

    Welcome to Cas Secured Spring Boot App

    +

    This is a Secured Page

    +

    Welcome home ${username!""}

    +
    +Logout + + \ No newline at end of file diff --git a/cas/cas-secured-app/src/test/java/com/baeldung/cassecuredapp/CasSecuredAppApplicationIntegrationTest.java b/cas/cas-secured-app/src/test/java/com/baeldung/cassecuredapp/CasSecuredAppApplicationIntegrationTest.java new file mode 100644 index 0000000000..2f2644e2ea --- /dev/null +++ b/cas/cas-secured-app/src/test/java/com/baeldung/cassecuredapp/CasSecuredAppApplicationIntegrationTest.java @@ -0,0 +1,16 @@ +package com.baeldung.cassecuredapp; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class CasSecuredAppApplicationIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/cas/cas-server/.gitignore b/cas/cas-server/.gitignore new file mode 100644 index 0000000000..5304519922 --- /dev/null +++ b/cas/cas-server/.gitignore @@ -0,0 +1,14 @@ +.classpath +!/.project +.project +.settings +target/ +.idea/ +.DS_Store +.idea +overlays/ +.gradle/ +build/ +bin/ +*.iml +*.log diff --git a/cas/cas-server/LICENSE.txt b/cas/cas-server/LICENSE.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/cas/cas-server/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/cas/cas-server/README.md b/cas/cas-server/README.md new file mode 100644 index 0000000000..bae8b648e5 --- /dev/null +++ b/cas/cas-server/README.md @@ -0,0 +1,88 @@ +CAS Overlay Template +============================ + +Generic CAS WAR overlay to exercise the latest versions of CAS. This overlay could be freely used as a starting template for local CAS war overlays. The CAS services management overlay is available [here](https://github.com/apereo/cas-services-management-overlay). + +# Versions + +```xml +5.1.x +``` + +# Requirements +* JDK 1.8+ + +# Configuration + +The `etc` directory contains the configuration files and directories that need to be copied to `/etc/cas/config`. + +# Build + +To see what commands are available to the build script, run: + +```bash +./build.sh help +``` + +To package the final web application, run: + +```bash +./build.sh package +``` + +To update `SNAPSHOT` versions run: + +```bash +./build.sh package -U +``` + +# Deployment + +- Create a keystore file `thekeystore` under `/etc/cas`. Use the password `changeit` for both the keystore and the key/certificate entries. +- Ensure the keystore is loaded up with keys and certificates of the server. + +On a successful deployment via the following methods, CAS will be available at: + +* `http://cas.server.name:8080/cas` +* `https://cas.server.name:8443/cas` + +## Executable WAR + +Run the CAS web application as an executable WAR. + +```bash +./build.sh run +``` + +## Spring Boot + +Run the CAS web application as an executable WAR via Spring Boot. This is most useful during development and testing. + +```bash +./build.sh bootrun +``` + +### Warning! + +Be careful with this method of deployment. `bootRun` is not designed to work with already executable WAR artifacts such that CAS server web application. YMMV. Today, uses of this mode ONLY work when there is **NO OTHER** dependency added to the build script and the `cas-server-webapp` is the only present module. See [this issue](https://github.com/apereo/cas/issues/2334) and [this issue](https://github.com/spring-projects/spring-boot/issues/8320) for more info. + + +## Spring Boot App Server Selection +There is an app.server property in the pom.xml that can be used to select a spring boot application server. +It defaults to "-tomcat" but "-jetty" and "-undertow" are supported. +It can also be set to an empty value (nothing) if you want to deploy CAS to an external application server of your choice and you don't want the spring boot libraries included. + +```xml +-tomcat +``` + +## Windows Build +If you are building on windows, try build.cmd instead of build.sh. Arguments are similar but for usage, run: + +``` +build.cmd help +``` + +## External + +Deploy resultant `target/cas.war` to a servlet container of choice. diff --git a/cas/cas-server/build.cmd b/cas/cas-server/build.cmd new file mode 100644 index 0000000000..f907dcb388 --- /dev/null +++ b/cas/cas-server/build.cmd @@ -0,0 +1,82 @@ +@echo off + +@set JAVA_ARGS=-Xms500m -Xmx1g +@set CAS_DIR=\etc\cas +@set CONFIG_DIR=\etc\cas\config + +@rem Call this script with DNAME and CERT_SUBJ_ALT_NAMES already set to override +@if "%DNAME%" == "" set DNAME=CN=cas.example.org,OU=Example,OU=Org,C=US +@rem List other host names or ip addresses you want in your certificate, may help with host name verification, +@rem if client apps make https connection for ticket validation and compare name in cert (include sub. alt. names) +@rem to name used to access CAS +@if "%CERT_SUBJ_ALT_NAMES%" == "" set CERT_SUBJ_ALT_NAMES=dns:example.org,dns:localhost,dns:%COMPUTERNAME%,ip:127.0.0.1 + +@rem Check for mvn in path, use it if found, otherwise use maven wrapper +@set MAVEN_CMD=mvn +@where /q mvn +@if %ERRORLEVEL% neq 0 set MAVEN_CMD=.\mvnw.bat + +@if "%1" == "" call:help +@if "%1" == "copy" call:copy +@if "%1" == "clean" call:clean %2 %3 %4 +@if "%1" == "package" call:package %2 %3 %4 +@if "%1" == "bootrun" call:bootrun %2 %3 %4 +@if "%1" == "debug" call:debug %2 %3 %4 +@if "%1" == "run" call:run %2 %3 %4 +@if "%1" == "help" call:help +@if "%1" == "gencert" call:gencert + +@rem function section starts here +@goto:eof + +:copy + @echo "Creating configuration directory under %CONFIG_DIR%" + if not exist %CONFIG_DIR% mkdir %CONFIG_DIR% + + @echo "Copying configuration files from etc/cas to /etc/cas" + xcopy /S /Y etc\cas\* \etc\cas +@goto:eof + +:help + @echo "Usage: build.bat [copy|clean|package|run|debug|bootrun|gencert] [optional extra args for maven]" + @echo "To get started on a clean system, run "build.bat copy" and "build.bat gencert", then "build.bat run" + @echo "Note that using the copy or gencert arguments will create and/or overwrite the %CAS_DIR% which is outside this project" +@goto:eof + +:clean + call %MAVEN_CMD% clean %1 %2 %3 + exit /B %ERRORLEVEL% +@goto:eof + +:package + call %MAVEN_CMD% clean package -T 5 %1 %2 %3 + exit /B %ERRORLEVEL% +@goto:eof + +:bootrun + call %MAVEN_CMD% clean package spring-boot:run -T 5 %1 %2 %3 + exit /B %ERRORLEVEL% +@goto:eof + +:debug + call:package %1 %2 %3 & java %JAVA_ARGS% -Xdebug -Xrunjdwp:transport=dt_socket,address=5000,server=y,suspend=n -jar target/cas.war +@goto:eof + +:run + call:package %1 %2 %3 & java %JAVA_ARGS% -jar target/cas.war +@goto:eof + +:gencert + where /q keytool + if ERRORLEVEL 1 ( + @echo Java keytool.exe not found in path. + exit /b 1 + ) else ( + if not exist %CAS_DIR% mkdir %CAS_DIR% + @echo on + @echo Generating self-signed SSL cert for %DNAME% in %CAS_DIR%\thekeystore + keytool -genkeypair -alias cas -keyalg RSA -keypass changeit -storepass changeit -keystore %CAS_DIR%\thekeystore -dname %DNAME% -ext SAN=%CERT_SUBJ_ALT_NAMES% + @echo Exporting cert for use in trust store (used by cas clients) + keytool -exportcert -alias cas -storepass changeit -keystore %CAS_DIR%\thekeystore -file %CAS_DIR%\cas.cer + ) +@goto:eof diff --git a/cas/cas-server/build.sh b/cas/cas-server/build.sh new file mode 100644 index 0000000000..e33f7de854 --- /dev/null +++ b/cas/cas-server/build.sh @@ -0,0 +1,97 @@ +#!/bin/bash + + +function copy() { + echo -e "Creating configuration directory under /etc/cas" + mkdir -p /etc/cas/config + + echo -e "Copying configuration files from etc/cas to /etc/cas" + cp -rfv etc/cas/* /etc/cas +} + +function help() { + echo "Usage: build.sh [copy|clean|package|run|debug|bootrun|gencert]" + echo " copy: Copy config from ./etc/cas/config to /etc/cas/config" + echo " clean: Clean Maven build directory" + echo " package: Clean and build CAS war, also call copy" + echo " run: Build and run CAS.war via spring boot (java -jar target/cas.war)" + echo " debug: Run CAS.war and listen for Java debugger on port 5000" + echo " bootrun: Run with maven spring boot plugin, doesn't work with multiple dependencies" + echo " gencert: Create keystore with SSL certificate in location where CAS looks by default" +} + +function clean() { + ./mvnw clean "$@" +} + +function package() { + ./mvnw clean package -T 5 "$@" + copy +} + +function bootrun() { + ./mvnw clean package spring-boot:run -T 5 "$@" +} + +function debug() { + package && java -Xdebug -Xrunjdwp:transport=dt_socket,address=5000,server=y,suspend=n -jar target/cas.war +} + +function run() { + package && java -jar target/cas.war +} + +function gencert() { + if [[ ! -d /etc/cas ]] ; then + copy + fi + which keytool + if [[ $? -ne 0 ]] ; then + echo Error: Java JDK \'keytool\' is not installed or is not in the path + exit 1 + fi + # override DNAME and CERT_SUBJ_ALT_NAMES before calling or use dummy values + DNAME="${DNAME:-CN=cas.example.org,OU=Example,OU=Org,C=US}" + CERT_SUBJ_ALT_NAMES="${CERT_SUBJ_ALT_NAMES:-dns:example.org,dns:localhost,ip:127.0.0.1}" + echo "Generating keystore for CAS with DN ${DNAME}" + keytool -genkeypair -alias cas -keyalg RSA -keypass changeit -storepass changeit -keystore /etc/cas/thekeystore -dname ${DNAME} -ext SAN=${CERT_SUBJ_ALT_NAMES} + keytool -exportcert -alias cas -storepass changeit -keystore /etc/cas/thekeystore -file /etc/cas/cas.cer +} + +if [ $# -eq 0 ]; then + echo -e "No commands provided. Defaulting to [run]\n" + run + exit 0 +fi + + +case "$1" in +"copy") + copy + ;; +"clean") + shift + clean "$@" + ;; +"package") + shift + package "$@" + ;; +"bootrun") + shift + bootrun "$@" + ;; +"debug") + debug "$@" + ;; +"run") + run "$@" + ;; +"gencert") + gencert "$@" + ;; +*) + help + ;; +esac + diff --git a/cas/cas-server/etc/cas/config/application.yml b/cas/cas-server/etc/cas/config/application.yml new file mode 100644 index 0000000000..be1f7c3edd --- /dev/null +++ b/cas/cas-server/etc/cas/config/application.yml @@ -0,0 +1,2 @@ +info: + description: CAS Configuration \ No newline at end of file diff --git a/cas/cas-server/etc/cas/config/cas.properties b/cas/cas-server/etc/cas/config/cas.properties new file mode 100644 index 0000000000..47a1477308 --- /dev/null +++ b/cas/cas-server/etc/cas/config/cas.properties @@ -0,0 +1,7 @@ +cas.server.name: https://cas.example.org:8443 +cas.server.prefix: https://cas.example.org:8443/cas + +cas.adminPagesSecurity.ip=127\.0\.0\.1 + +logging.config: file:/etc/cas/config/log4j2.xml +# cas.serviceRegistry.config.location: classpath:/services diff --git a/cas/cas-server/etc/cas/config/log4j2.xml b/cas/cas-server/etc/cas/config/log4j2.xml new file mode 100644 index 0000000000..53b30b4228 --- /dev/null +++ b/cas/cas-server/etc/cas/config/log4j2.xml @@ -0,0 +1,117 @@ + + + + + + . + + warn + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cas/cas-server/maven/maven-wrapper.properties b/cas/cas-server/maven/maven-wrapper.properties new file mode 100644 index 0000000000..b368e4609a --- /dev/null +++ b/cas/cas-server/maven/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https\://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip diff --git a/cas/cas-server/mvnw b/cas/cas-server/mvnw new file mode 100644 index 0000000000..2275ac7647 --- /dev/null +++ b/cas/cas-server/mvnw @@ -0,0 +1,234 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # + # Look for the Apple JDKs first to preserve the existing behaviour, and then look + # for the new JDKs provided by Oracle. + # + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then + # + # Oracle JDKs + # + export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then + # + # Apple JDKs + # + export JAVA_HOME=`/usr/libexec/java_home` + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + local basedir=$(pwd) + local wdir=$(pwd) + while [ "$wdir" != '/' ] ; do + wdir=$(cd "$wdir/.."; pwd) + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER="org.apache.maven.wrapper.MavenWrapperMain" + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + -classpath \ +"$MAVEN_PROJECTBASEDIR/maven/maven-wrapper.jar" \ + ${WRAPPER_LAUNCHER} "$@" diff --git a/cas/cas-server/mvnw.bat b/cas/cas-server/mvnw.bat new file mode 100644 index 0000000000..d391151aa7 --- /dev/null +++ b/cas/cas-server/mvnw.bat @@ -0,0 +1,174 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto chkMHome + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:chkMHome +if not "%M2_HOME%"=="" goto valMHome + +SET "M2_HOME=%~dp0.." +if not "%M2_HOME%"=="" goto valMHome + +echo. +echo Error: M2_HOME not found in your environment. >&2 +echo Please set the M2_HOME variable in your environment to match the >&2 +echo location of the Maven installation. >&2 +echo. +goto error + +:valMHome + +:stripMHome +if not "_%M2_HOME:~-1%"=="_\" goto checkMCmd +set "M2_HOME=%M2_HOME:~0,-1%" +goto stripMHome + +:checkMCmd +if exist "%M2_HOME%\bin\mvn.cmd" goto init + +echo. +echo Error: M2_HOME is set to an invalid directory. >&2 +echo M2_HOME = "%M2_HOME%" >&2 +echo Please set the M2_HOME variable in your environment to match the >&2 +echo location of the Maven installation >&2 +echo. +goto error +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%* + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\maven\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% + +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/cas/cas-server/pom.xml b/cas/cas-server/pom.xml new file mode 100644 index 0000000000..e8625b48f7 --- /dev/null +++ b/cas/cas-server/pom.xml @@ -0,0 +1,158 @@ + + + 4.0.0 + com.baeldung + cas-server + war + 1.0 + + + + + com.rimerosolutions.maven.plugins + wrapper-maven-plugin + 0.0.4 + + true + MD5 + + + + org.springframework.boot + spring-boot-maven-plugin + ${springboot.version} + + org.springframework.boot.loader.WarLauncher + true + + + + org.apache.maven.plugins + maven-war-plugin + 2.6 + + cas + false + false + + false + ${project.build.directory}/war/work/org.apereo.cas/cas-server-webapp${app.server}/META-INF/MANIFEST.MF + + + + + org.apereo.cas + cas-server-webapp${app.server} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + + cas + + + + + org.apereo.cas + cas-server-webapp${app.server} + ${cas.version} + war + runtime + + + org.apereo.cas + cas-server-support-json-service-registry + ${cas.version} + + + org.apereo.cas + cas-server-support-jdbc + ${cas.version} + + + org.apereo.cas + cas-server-support-jdbc-drivers + ${cas.version} + + + + + 5.1.4 + 1.5.3.RELEASE + + -tomcat + 1.8 + 1.8 + UTF-8 + + + + + sonatype-releases + http://oss.sonatype.org/content/repositories/releases/ + + false + + + true + + + + sonatype-snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + true + + + false + + + + shibboleth-releases + https://build.shibboleth.net/nexus/content/repositories/releases + + + spring-milestones + https://repo.spring.io/milestone + + + + + + + false + + pgp + + + + com.github.s4u.plugins + pgpverify-maven-plugin + 1.1.0 + + + + check + + + + + hkp://pool.sks-keyservers.net + ${settings.localRepository}/pgpkeys-cache + test + true + false + + + + + + + diff --git a/cas/cas-server/src/main/resources/application.properties b/cas/cas-server/src/main/resources/application.properties new file mode 100644 index 0000000000..018fd351ff --- /dev/null +++ b/cas/cas-server/src/main/resources/application.properties @@ -0,0 +1,134 @@ +## +# CAS Server Context Configuration +# +server.context-path=/cas +server.port=6443 + +server.ssl.key-store=classpath:/etc/cas/thekeystore +server.ssl.key-store-password=changeit +server.ssl.key-password=changeit +# server.ssl.ciphers= +# server.ssl.client-auth= +# server.ssl.enabled= +# server.ssl.key-alias= +# server.ssl.key-store-provider= +# server.ssl.key-store-type= +# server.ssl.protocol= +# server.ssl.trust-store= +# server.ssl.trust-store-password= +# server.ssl.trust-store-provider= +# server.ssl.trust-store-type= + +server.max-http-header-size=2097152 +server.use-forward-headers=true +server.connection-timeout=20000 +server.error.include-stacktrace=NEVER + +server.tomcat.max-http-post-size=2097152 +server.tomcat.basedir=build/tomcat +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms) +server.tomcat.accesslog.suffix=.log +server.tomcat.max-threads=10 +server.tomcat.port-header=X-Forwarded-Port +server.tomcat.protocol-header=X-Forwarded-Proto +server.tomcat.protocol-header-https-value=https +server.tomcat.remote-ip-header=X-FORWARDED-FOR +server.tomcat.uri-encoding=UTF-8 + +spring.http.encoding.charset=UTF-8 +spring.http.encoding.enabled=true +spring.http.encoding.force=true + +## +#CAS CONFIG LOCATION +# +cas.standalone.config=classpath:/etc/cas/config + + +## +# CAS Cloud Bus Configuration +# +spring.cloud.bus.enabled=false +# spring.cloud.bus.refresh.enabled=true +# spring.cloud.bus.env.enabled=true +# spring.cloud.bus.destination=CasCloudBus +# spring.cloud.bus.ack.enabled=true + +endpoints.enabled=false +endpoints.sensitive=true + +endpoints.restart.enabled=false +endpoints.shutdown.enabled=false + +management.security.enabled=true +management.security.roles=ACTUATOR,ADMIN +management.security.sessions=if_required +management.context-path=/status +management.add-application-context-header=false + +security.basic.authorize-mode=role +security.basic.enabled=false +security.basic.path=/cas/status/** + +## +# CAS Web Application Session Configuration +# +server.session.timeout=300 +server.session.cookie.http-only=true +server.session.tracking-modes=COOKIE + +## +# CAS Thymeleaf View Configuration +# +spring.thymeleaf.encoding=UTF-8 +spring.thymeleaf.cache=true +spring.thymeleaf.mode=HTML +## +# CAS Log4j Configuration +# +# logging.config=file:/etc/cas/log4j2.xml + +server.context-parameters.isLog4jAutoInitializationDisabled=true + +## +# CAS AspectJ Configuration +# +spring.aop.auto=true +spring.aop.proxy-target-class=true + +## +# CAS Authentication Credentials +# +#cas.authn.accept.users=casuser::Mellon +cas.authn.accept.users= +cas.authn.accept.name= + +#CAS Database Authentication Property +cas.authn.jdbc.query[0].sql=SELECT * FROM users WHERE email = ? +cas.authn.jdbc.query[0].url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC +cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect +cas.authn.jdbc.query[0].user=root +cas.authn.jdbc.query[0].password=root +cas.authn.jdbc.query[0].ddlAuto=none +#cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver +cas.authn.jdbc.query[0].driverClass=com.mysql.cj.jdbc.Driver +cas.authn.jdbc.query[0].fieldPassword=password +cas.authn.jdbc.query[0].passwordEncoder.type=NONE + + +## +# CAS Delegated Authentication +# +cas.authn.pac4j.bitbucket.clientName=Bitbucket +cas.authn.pac4j.dropbox.clientName=Dropbox +cas.authn.pac4j.facebook.clientName=Facebook +cas.authn.pac4j.foursquare.clientName=Foursquare +cas.authn.pac4j.github.clientName=Github +cas.authn.pac4j.google.clientName=Google +cas.authn.pac4j.linkedIn.clientName=LinkedIn +cas.authn.pac4j.paypal.clientName=PayPal +cas.authn.pac4j.twitter.clientName=Twitter +cas.authn.pac4j.yahoo.clientName=Yahoo +cas.authn.pac4j.windowsLive.clientName=Windows Live +cas.authn.pac4j.wordpress.clientName=WordPress diff --git a/cas/cas-server/src/main/resources/cas.properties b/cas/cas-server/src/main/resources/cas.properties new file mode 100644 index 0000000000..f80f22fc11 --- /dev/null +++ b/cas/cas-server/src/main/resources/cas.properties @@ -0,0 +1,40 @@ +cas.server.name: https://localhost:6443 +cas.server.prefix: https://localhost:643/cas + +cas.adminPagesSecurity.ip=127\.0\.0\.1 + +cas.serviceRegistry.initFromJson=true +cas.serviceRegistry.config.location=classpath:/services + +cas.authn.accept.users= +cas.authn.accept.name= + + +#CAS Database Authentication Property + +# cas.authn.jdbc.query[0].healthQuery= +# cas.authn.jdbc.query[0].isolateInternalQueries=false +# cas.authn.jdbc.query[0].failFast=true +# cas.authn.jdbc.query[0].isolationLevelName=ISOLATION_READ_COMMITTED +# cas.authn.jdbc.query[0].leakThreshold=10 +# cas.authn.jdbc.query[0].propagationBehaviorName=PROPAGATION_REQUIRED +# cas.authn.jdbc.query[0].batchSize=1 +# cas.authn.jdbc.query[0].maxAgeDays=180 +# cas.authn.jdbc.query[0].autocommit=false +# cas.authn.jdbc.query[0].idleTimeout=5000 +# cas.authn.jdbc.query[0].credentialCriteria= +# cas.authn.jdbc.query[0].name= +# cas.authn.jdbc.query[0].order=0 +# cas.authn.jdbc.query[0].dataSourceName= +# cas.authn.jdbc.query[0].dataSourceProxy=false +# cas.authn.jdbc.query[0].fieldExpired= +# cas.authn.jdbc.query[0].fieldDisabled= +# cas.authn.jdbc.query[0].principalAttributeList=sn,cn:commonName,givenName +# cas.authn.jdbc.query[0].passwordEncoder.type=NONE|DEFAULT|STANDARD|BCRYPT|SCRYPT|PBKDF2|com.example.CustomPasswordEncoder +# cas.authn.jdbc.query[0].passwordEncoder.characterEncoding= +# cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm= +# cas.authn.jdbc.query[0].passwordEncoder.secret= +# cas.authn.jdbc.query[0].passwordEncoder.strength=16 +# cas.authn.jdbc.query[0].principalTransformation.suffix= +# cas.authn.jdbc.query[0].principalTransformation.caseConversion=NONE|UPPERCASE|LOWERCASE +# cas.authn.jdbc.query[0].principalTransformation.prefix= \ No newline at end of file diff --git a/cas/cas-server/src/main/resources/create_test_db_and_users_tbl.sql b/cas/cas-server/src/main/resources/create_test_db_and_users_tbl.sql new file mode 100644 index 0000000000..79a4a48a82 --- /dev/null +++ b/cas/cas-server/src/main/resources/create_test_db_and_users_tbl.sql @@ -0,0 +1,16 @@ +-- Dumping database structure for test +CREATE DATABASE IF NOT EXISTS `test` /*!40100 DEFAULT CHARACTER SET latin1 */; +USE `test`; + +-- Dumping structure for table test.users +CREATE TABLE IF NOT EXISTS `users` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `email` varchar(50) DEFAULT NULL, + `password` text DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; + +/*!40000 ALTER TABLE `users` DISABLE KEYS */; +INSERT INTO `users` (`id`, `email`, `password`) VALUES + (1, 'test@test.com', 'Mellon'); +/*!40000 ALTER TABLE `users` ENABLE KEYS */; \ No newline at end of file diff --git a/cas/cas-server/src/main/resources/etc/cas/config/application.yml b/cas/cas-server/src/main/resources/etc/cas/config/application.yml new file mode 100644 index 0000000000..be1f7c3edd --- /dev/null +++ b/cas/cas-server/src/main/resources/etc/cas/config/application.yml @@ -0,0 +1,2 @@ +info: + description: CAS Configuration \ No newline at end of file diff --git a/cas/cas-server/src/main/resources/etc/cas/config/cas.properties b/cas/cas-server/src/main/resources/etc/cas/config/cas.properties new file mode 100644 index 0000000000..47a1477308 --- /dev/null +++ b/cas/cas-server/src/main/resources/etc/cas/config/cas.properties @@ -0,0 +1,7 @@ +cas.server.name: https://cas.example.org:8443 +cas.server.prefix: https://cas.example.org:8443/cas + +cas.adminPagesSecurity.ip=127\.0\.0\.1 + +logging.config: file:/etc/cas/config/log4j2.xml +# cas.serviceRegistry.config.location: classpath:/services diff --git a/cas/cas-server/src/main/resources/etc/cas/config/log4j2.xml b/cas/cas-server/src/main/resources/etc/cas/config/log4j2.xml new file mode 100644 index 0000000000..53b30b4228 --- /dev/null +++ b/cas/cas-server/src/main/resources/etc/cas/config/log4j2.xml @@ -0,0 +1,117 @@ + + + + + + . + + warn + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cas/cas-server/src/main/resources/etc/cas/thekeystore b/cas/cas-server/src/main/resources/etc/cas/thekeystore new file mode 100644 index 0000000000..86170dff16 Binary files /dev/null and b/cas/cas-server/src/main/resources/etc/cas/thekeystore differ diff --git a/cas/cas-server/src/main/resources/etc/cas/thekeystore.crt b/cas/cas-server/src/main/resources/etc/cas/thekeystore.crt new file mode 100644 index 0000000000..5bd9d5baba Binary files /dev/null and b/cas/cas-server/src/main/resources/etc/cas/thekeystore.crt differ diff --git a/cas/cas-server/src/main/resources/services/casSecuredApp.json b/cas/cas-server/src/main/resources/services/casSecuredApp.json new file mode 100644 index 0000000000..336007e484 --- /dev/null +++ b/cas/cas-server/src/main/resources/services/casSecuredApp.json @@ -0,0 +1,8 @@ +{ + "@class" : "org.apereo.cas.services.RegexRegisteredService", + "serviceId" : "^http://localhost:9000/login/cas", + "name" : "CAS Spring Secured App", + "description": "This is a Spring App that usses the CAS Server for it's authentication", + "id" : 19991, + "evaluationOrder" : 1 +} \ No newline at end of file diff --git a/core-java-8/README.md b/core-java-8/README.md index 4610b3c86d..540a32b0ba 100644 --- a/core-java-8/README.md +++ b/core-java-8/README.md @@ -28,5 +28,7 @@ - [Finding Max/Min of a List or Collection](http://www.baeldung.com/java-collection-min-max) - [Java Base64 Encoding and Decoding](http://www.baeldung.com/java-base64-encode-and-decode) - [The Difference Between map() and flatMap()](http://www.baeldung.com/java-difference-map-and-flatmap) - -- [Merging Streams in Java](http://www.baeldung.com/java-merge-streams) \ No newline at end of file +- [Merging Streams in Java](http://www.baeldung.com/java-merge-streams) +- [“Stream has already been operated upon or closed” Exception in Java](http://www.baeldung.com/java-stream-operated-upon-or-closed-exception) +- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones) +- [Copy a File with Java](http://www.baeldung.com/java-copy-file) diff --git a/core-java-8/pom.xml b/core-java-8/pom.xml index f5506f095e..17d330b3b8 100644 --- a/core-java-8/pom.xml +++ b/core-java-8/pom.xml @@ -1,258 +1,276 @@ - - 4.0.0 - com.baeldung - core-java-8 - 0.1.0-SNAPSHOT - jar - - core-java-8 - - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - - - com.google.guava - guava - ${guava.version} - - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - - - - commons-io - commons-io - ${commons-io.version} - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - - org.apache.commons - commons-math3 - ${commons-math3.version} - - - - log4j - log4j - 1.2.17 - - - - commons-codec - commons-codec - ${commons-codec.version} - - - - org.projectlombok - lombok - ${lombok.version} - provided - - - - - - org.assertj - assertj-core - ${assertj.version} - test - - - - com.jayway.awaitility - awaitility - ${avaitility.version} - test - - - - - - core-java-8 - - - src/main/resources - true - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - libs/ - org.baeldung.executable.ExecutableMavenJar - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - ${project.basedir} - - - org.baeldung.executable.ExecutableMavenJar - - - - jar-with-dependencies - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - - true - - - org.baeldung.executable.ExecutableMavenJar - - - - - - - - com.jolira - onejar-maven-plugin - - - - org.baeldung.executable.ExecutableMavenJar - true - ${project.build.finalName}-onejar.${project.packaging} - - - one-jar - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - spring-boot - org.baeldung.executable.ExecutableMavenJar - - - - - - - - - - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - - - **/*IntegrationTest.java - - - - - - - json - - - - - - - - - - - - 21.0 - 3.5 - 3.6.1 - 2.5 - 4.1 - 4.01 - 1.10 - 1.16.12 - - - 3.6.1 - 1.7.0 - - + + 4.0.0 + com.baeldung + core-java-8 + 0.1.0-SNAPSHOT + jar + + core-java-8 + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + + com.google.guava + guava + ${guava.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + commons-io + commons-io + ${commons-io.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + + log4j + log4j + 1.2.17 + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + com.jayway.awaitility + awaitility + ${avaitility.version} + test + + + + org.openjdk.jmh + jmh-core + 1.19 + + + + org.openjdk.jmh + jmh-generator-annprocess + 1.19 + + + + org.openjdk.jmh + jmh-generator-bytecode + 1.19 + + + + + + core-java-8 + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/libs + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + org.baeldung.executable.ExecutableMavenJar + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + ${project.basedir} + + + org.baeldung.executable.ExecutableMavenJar + + + + jar-with-dependencies + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + shade + + + true + + + org.baeldung.executable.ExecutableMavenJar + + + + + + + + com.jolira + onejar-maven-plugin + + + + org.baeldung.executable.ExecutableMavenJar + true + ${project.build.finalName}-onejar.${project.packaging} + + + one-jar + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + spring-boot + org.baeldung.executable.ExecutableMavenJar + + + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + + + 21.0 + 3.5 + 3.6.1 + 2.5 + 4.1 + 4.01 + 1.10 + 1.16.12 + + + 3.6.1 + 1.7.0 + + \ No newline at end of file diff --git a/core-java-8/src/main/java/com/baeldung/annotations/ClassWithAnnotation.java b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithAnnotation.java new file mode 100644 index 0000000000..034e6785a4 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithAnnotation.java @@ -0,0 +1,5 @@ +package com.baeldung.annotations; + +@Deprecated +class ClassWithAnnotation { +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/ClassWithDeprecatedMethod.java b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithDeprecatedMethod.java new file mode 100644 index 0000000000..6f5da03b74 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithDeprecatedMethod.java @@ -0,0 +1,9 @@ +package com.baeldung.annotations; + +class ClassWithDeprecatedMethod { + + @Deprecated + static void deprecatedMethod() { + + } +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSafeVarargs.java b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSafeVarargs.java new file mode 100644 index 0000000000..cfa91f5951 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSafeVarargs.java @@ -0,0 +1,11 @@ +package com.baeldung.annotations; + +class ClassWithSafeVarargs { + + @SafeVarargs + final void iterateOverVarargs(T... args) { + for (T x : args) { + // do stuff with x + } + } +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSuppressWarnings.java b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSuppressWarnings.java new file mode 100644 index 0000000000..fe22ec1c24 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSuppressWarnings.java @@ -0,0 +1,9 @@ +package com.baeldung.annotations; + +class ClassWithSuppressWarnings { + + @SuppressWarnings("deprecation") + void useDeprecatedMethod() { + ClassWithDeprecatedMethod.deprecatedMethod(); // no warning is generated here + } +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/IntConsumer.java b/core-java-8/src/main/java/com/baeldung/annotations/IntConsumer.java new file mode 100644 index 0000000000..4f16b27281 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/IntConsumer.java @@ -0,0 +1,8 @@ +package com.baeldung.annotations; + +@FunctionalInterface +interface IntConsumer { + + void accept(Integer number); + +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/Interval.java b/core-java-8/src/main/java/com/baeldung/annotations/Interval.java new file mode 100644 index 0000000000..f73e6e5b14 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/Interval.java @@ -0,0 +1,8 @@ +package com.baeldung.annotations; + +import java.lang.annotation.Repeatable; + +@Repeatable(Intervals.class) +@interface Interval { + int hour() default 1; +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/IntervalUsage.java b/core-java-8/src/main/java/com/baeldung/annotations/IntervalUsage.java new file mode 100644 index 0000000000..2e11de8215 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/IntervalUsage.java @@ -0,0 +1,9 @@ +package com.baeldung.annotations; + +public class IntervalUsage { + + @Interval(hour = 17) + @Interval(hour = 13) + void doPeriodicCleanup() { + } +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/Intervals.java b/core-java-8/src/main/java/com/baeldung/annotations/Intervals.java new file mode 100644 index 0000000000..af469f18cc --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/Intervals.java @@ -0,0 +1,5 @@ +package com.baeldung.annotations; + +@interface Intervals { + Interval[] value(); +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotation.java b/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotation.java new file mode 100644 index 0000000000..6e71f446b0 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotation.java @@ -0,0 +1,11 @@ +package com.baeldung.annotations; + +import java.lang.annotation.*; + +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.LOCAL_VARIABLE, ElementType.FIELD}) +@interface MyAnnotation { + +} \ No newline at end of file diff --git a/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotationTarget.java b/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotationTarget.java new file mode 100644 index 0000000000..37f40a624e --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotationTarget.java @@ -0,0 +1,16 @@ +package com.baeldung.annotations; + +class MyAnnotationTarget { + + // this is OK + @MyAnnotation + String someField; + + // @MyAnnotation <- this is invalid usage! + void doSomething() { + + // this also works + @MyAnnotation + String localVariable; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/MyOperation.java b/core-java-8/src/main/java/com/baeldung/annotations/MyOperation.java new file mode 100644 index 0000000000..a4385bc786 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/MyOperation.java @@ -0,0 +1,6 @@ +package com.baeldung.annotations; + +interface MyOperation { + + void perform(); +} \ No newline at end of file diff --git a/core-java-8/src/main/java/com/baeldung/annotations/MyOperationImpl.java b/core-java-8/src/main/java/com/baeldung/annotations/MyOperationImpl.java new file mode 100644 index 0000000000..e6a8ce76d3 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/MyOperationImpl.java @@ -0,0 +1,9 @@ +package com.baeldung.annotations; + +class MyOperationImpl implements MyOperation { + + @Override + public void perform() { + + } +} \ No newline at end of file diff --git a/core-java-8/src/main/java/com/baeldung/prime/PrimeGenerator.java b/core-java-8/src/main/java/com/baeldung/prime/PrimeGenerator.java new file mode 100644 index 0000000000..750807ce77 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/prime/PrimeGenerator.java @@ -0,0 +1,59 @@ +package com.baeldung.prime; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class PrimeGenerator { + public static List sieveOfEratosthenes(int n) { + final boolean prime[] = new boolean[n + 1]; + Arrays.fill(prime, true); + + for (int p = 2; p * p <= n; p++) { + if (prime[p]) { + for (int i = p * 2; i <= n; i += p) + prime[i] = false; + } + } + + final List primes = new LinkedList<>(); + for (int i = 2; i <= n; i++) { + if (prime[i]) + primes.add(i); + } + return primes; + } + + public static List primeNumbersBruteForce(int max) { + final List primeNumbers = new LinkedList(); + for (int i = 2; i <= max; i++) { + if (isPrimeBruteForce(i)) { + primeNumbers.add(i); + } + } + return primeNumbers; + } + + private static boolean isPrimeBruteForce(int x) { + for (int i = 2; i < x; i++) { + if (x % i == 0) { + return false; + } + } + return true; + } + + public static List primeNumbersTill(int max) { + return IntStream.rangeClosed(2, max) + .filter(x -> isPrime(x)) + .boxed() + .collect(Collectors.toList()); + } + + private static boolean isPrime(int x) { + return IntStream.rangeClosed(2, (int) (Math.sqrt(x))) + .allMatch(n -> x % n != 0); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java b/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java new file mode 100644 index 0000000000..3a1016c63b --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java @@ -0,0 +1,55 @@ +package com.baeldung.timezonedisplay; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class TimezoneDisplay { + + public enum OffsetBase { + GMT, UTC + } + + public List getTimeZoneList(OffsetBase base) { + Set availableZoneIds = ZoneId.getAvailableZoneIds(); + + LocalDateTime now = LocalDateTime.now(); + return availableZoneIds + .stream() + .map(ZoneId::of) + .sorted(new ZoneComparator()) + .map(id -> String.format("(%s%s) %s", base, getOffset(now, id), id.getId())) + .collect(Collectors.toList()); + } + + private String getOffset(LocalDateTime dateTime, ZoneId id) { + return dateTime + .atZone(id) + .getOffset() + .getId() + .replace("Z", "+00:00"); + } + + private class ZoneComparator implements Comparator { + + @Override + public int compare(ZoneId zoneId1, ZoneId zoneId2) { + LocalDateTime now = LocalDateTime.now(); + + ZoneOffset offset1 = now + .atZone(zoneId1) + .getOffset(); + + ZoneOffset offset2 = now + .atZone(zoneId2) + .getOffset(); + + return offset1.compareTo(offset2); + } + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java b/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java new file mode 100644 index 0000000000..aa9f84e21a --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java @@ -0,0 +1,18 @@ +package com.baeldung.timezonedisplay; + +import java.util.List; + +public class TimezoneDisplayApp { + + public static void main(String... args) { + TimezoneDisplay display = new TimezoneDisplay(); + + System.out.println("Time zones in UTC:"); + List utc = display.getTimeZoneList(TimezoneDisplay.OffsetBase.UTC); + utc.forEach(System.out::println); + + System.out.println("Time zones in GMT:"); + List gmt = display.getTimeZoneList(TimezoneDisplay.OffsetBase.GMT); + gmt.forEach(System.out::println); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/counter/CounterStatistics.java b/core-java-8/src/test/java/com/baeldung/counter/CounterStatistics.java new file mode 100644 index 0000000000..2a42a166fa --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/counter/CounterStatistics.java @@ -0,0 +1,45 @@ +package com.baeldung.counter; + +import java.util.HashMap; +import java.util.Map; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; + +import com.baeldung.counter.CounterUtil.MutableInteger; + +@Fork(value = 1, warmups = 3) +@BenchmarkMode(Mode.All) +public class CounterStatistics { + + private static final Map counterMap = new HashMap<>(); + private static final Map counterWithMutableIntMap = new HashMap<>(); + private static final Map counterWithIntArrayMap = new HashMap<>(); + private static final Map counterWithLongWrapperMap = new HashMap<>(); + + @Benchmark + public void wrapperAsCounter() { + CounterUtil.counterWithWrapperObject(counterMap); + } + + @Benchmark + public void lambdaExpressionWithWrapper() { + CounterUtil.counterWithLambdaAndWrapper(counterWithLongWrapperMap); + } + + @Benchmark + public void mutableIntegerAsCounter() { + CounterUtil.counterWithMutableInteger(counterWithMutableIntMap); + } + + @Benchmark + public void primitiveArrayAsCounter() { + CounterUtil.counterWithPrimitiveArray(counterWithIntArrayMap); + } + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/counter/CounterTest.java b/core-java-8/src/test/java/com/baeldung/counter/CounterTest.java new file mode 100644 index 0000000000..657b510452 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/counter/CounterTest.java @@ -0,0 +1,53 @@ +package com.baeldung.counter; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import com.baeldung.counter.CounterUtil.MutableInteger; + +public class CounterTest { + + @Test + public void whenMapWithWrapperAsCounter_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithWrapperObject(counterMap); + + assertEquals(3, counterMap.get("China") + .intValue()); + assertEquals(2, counterMap.get("India") + .intValue()); + } + + @Test + public void whenMapWithLambdaAndWrapperCounter_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithLambdaAndWrapper(counterMap); + + assertEquals(3l, counterMap.get("China") + .longValue()); + assertEquals(2l, counterMap.get("India") + .longValue()); + } + + @Test + public void whenMapWithMutableIntegerCounter_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithMutableInteger(counterMap); + assertEquals(3, counterMap.get("China") + .getCount()); + assertEquals(2, counterMap.get("India") + .getCount()); + } + + @Test + public void whenMapWithPrimitiveArray_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithPrimitiveArray(counterMap); + assertEquals(3, counterMap.get("China")[0]); + assertEquals(2, counterMap.get("India")[0]); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/counter/CounterUtil.java b/core-java-8/src/test/java/com/baeldung/counter/CounterUtil.java new file mode 100644 index 0000000000..647fbfb0cc --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/counter/CounterUtil.java @@ -0,0 +1,61 @@ +package com.baeldung.counter; + +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class CounterUtil { + + private final static String[] COUNTRY_NAMES = { "China", "Australia", "India", "USA", "USSR", "UK", "China", "France", "Poland", "Austria", "India", "USA", "Egypt", "China" }; + + public static void counterWithWrapperObject(Map counterMap) { + for (String country : COUNTRY_NAMES) { + counterMap.compute(country, (k, v) -> v == null ? 1 : v + 1); + } + } + + public static void counterWithLambdaAndWrapper(Map counterMap) { + counterMap.putAll(Stream.of(COUNTRY_NAMES) + .parallel() + .collect(Collectors.groupingBy(k -> k, Collectors.counting()))); + } + + public static class MutableInteger { + int count; + + public MutableInteger(int count) { + this.count = count; + } + + public void increment() { + this.count++; + } + + public int getCount() { + return this.count; + } + } + + public static void counterWithMutableInteger(Map counterMap) { + for (String country : COUNTRY_NAMES) { + MutableInteger oldValue = counterMap.get(country); + if (oldValue != null) { + oldValue.increment(); + } else { + counterMap.put(country, new MutableInteger(1)); + } + } + } + + public static void counterWithPrimitiveArray(Map counterMap) { + for (String country : COUNTRY_NAMES) { + int[] oldCounter = counterMap.get(country); + if (oldCounter != null) { + oldCounter[0] += 1; + } else { + counterMap.put(country, new int[] { 1 }); + } + } + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/prime/PrimeGeneratorTest.java b/core-java-8/src/test/java/com/baeldung/prime/PrimeGeneratorTest.java new file mode 100644 index 0000000000..e53e1c183e --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/prime/PrimeGeneratorTest.java @@ -0,0 +1,28 @@ +package com.baeldung.prime; + +import static com.baeldung.prime.PrimeGenerator.*; + +import java.util.Arrays; +import java.util.List; +import org.junit.Test; +import static org.junit.Assert.*; + +public class PrimeGeneratorTest { + @Test + public void whenBruteForced_returnsSuccessfully() { + final List primeNumbers = primeNumbersBruteForce(20); + assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers); + } + + @Test + public void whenOptimized_returnsSuccessfully() { + final List primeNumbers = primeNumbersTill(20); + assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers); + } + + @Test + public void whenSieveOfEratosthenes_returnsSuccessfully() { + final List primeNumbers = sieveOfEratosthenes(20); + assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/stream/SupplierStreamTest.java b/core-java-8/src/test/java/com/baeldung/stream/SupplierStreamTest.java new file mode 100644 index 0000000000..d78c9fca35 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/stream/SupplierStreamTest.java @@ -0,0 +1,35 @@ +package com.baeldung.stream; + +import static org.junit.Assert.fail; + +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import org.junit.Test; + +public class SupplierStreamTest { + + @Test(expected = IllegalStateException.class) + public void givenStream_whenStreamUsedTwice_thenThrowException() { + Stream stringStream = Stream.of("A", "B", "C", "D"); + Optional result1 = stringStream.findAny(); + System.out.println(result1.get()); + Optional result2 = stringStream.findFirst(); + System.out.println(result2.get()); + } + + @Test + public void givenStream_whenUsingSupplier_thenNoExceptionIsThrown() { + try { + Supplier> streamSupplier = () -> Stream.of("A", "B", "C", "D"); + Optional result1 = streamSupplier.get().findAny(); + System.out.println(result1.get()); + Optional result2 = streamSupplier.get().findFirst(); + System.out.println(result2.get()); + } catch (IllegalStateException e) { + fail(); + } + } + +} \ No newline at end of file diff --git a/core-java-9/README.md b/core-java-9/README.md index 22d6903f06..98c855caea 100644 --- a/core-java-9/README.md +++ b/core-java-9/README.md @@ -8,7 +8,7 @@ - [Java 9 Stream API Improvements](http://www.baeldung.com/java-9-stream-api) - [Java 9 Convenience Factory Methods for Collections](http://www.baeldung.com/java-9-collections-factory-methods) - [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors) -- [Java 9 CompletableFuture API Improvements](http://www.baeldung.com/java9-completablefuture-api-improvements/) +- [Java 9 CompletableFuture API Improvements](http://www.baeldung.com/java-9-completablefuture) - [Spring Security – Redirect to the Previous URL After Login](http://www.baeldung.com/spring-security-redirect-login) - [Java 9 Process API Improvements](http://www.baeldung.com/java-9-process-api) - [Introduction to Java 9 StackWalking API](http://www.baeldung.com/java-9-stackwalking-api) @@ -16,3 +16,5 @@ - [Java 9 Optional API Additions](http://www.baeldung.com/java-9-optional) - [Java 9 Reactive Streams](http://www.baeldung.com/java-9-reactive-streams) - [How to Get All Dates Between Two Dates?](http://www.baeldung.com/java-between-dates) +- [Java 9 java.util.Objects Additions](http://www.baeldung.com/java-9-objects-new) +- [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string) diff --git a/core-java-9/compile-httpclient.bat b/core-java-9/compile-httpclient.bat new file mode 100644 index 0000000000..9d845784cf --- /dev/null +++ b/core-java-9/compile-httpclient.bat @@ -0,0 +1,3 @@ +javac --module-path mods -d mods/com.baeldung.httpclient^ + src/modules/com.baeldung.httpclient/module-info.java^ + src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java \ No newline at end of file diff --git a/core-java-9/run-httpclient.bat b/core-java-9/run-httpclient.bat new file mode 100644 index 0000000000..60b1eb7f68 --- /dev/null +++ b/core-java-9/run-httpclient.bat @@ -0,0 +1 @@ +java --module-path mods -m com.baeldung.httpclient/com.baeldung.httpclient.HttpClientExample \ No newline at end of file diff --git a/core-java-9/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java b/core-java-9/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java new file mode 100644 index 0000000000..cb24511f72 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/compactstring/CompactStringDemo.java @@ -0,0 +1,24 @@ +package com.baeldung.java9.compactstring; + +import java.util.List; +import static java.util.stream.Collectors.toList; +import java.util.stream.IntStream; + +public class CompactStringDemo { + + public static void main(String[] args) { + long startTime = System.currentTimeMillis(); + List strings = IntStream.rangeClosed(1, 10_000_000) + .mapToObj(Integer::toString).collect(toList()); + long totalTime = System.currentTimeMillis() - startTime; + System.out.println("Generated " + strings.size() + " strings in " + + totalTime + " ms."); + + startTime = System.currentTimeMillis(); + String appended = (String) strings.stream().limit(100_000) + .reduce("", (left, right) -> left.toString() + right.toString()); + totalTime = System.currentTimeMillis() - startTime; + System.out.println("Created string of length " + appended.length() + + " in " + totalTime + " ms."); + } +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java b/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java new file mode 100644 index 0000000000..c794c57e87 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java @@ -0,0 +1,39 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; + +/** + * Class which shows a way to convert java.util.Date into java.time.LocalDate. + * + * @author abialas + * + */ +public class DateToLocalDateConverter { + + public static LocalDate convertToLocalDateViaInstant(Date dateToConvert) { + return dateToConvert.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate(); + } + + public static LocalDate convertToLocalDateViaSqlDate(Date dateToConvert) { + return new java.sql.Date(dateToConvert.getTime()).toLocalDate(); + } + + public static LocalDate convertToLocalDateViaMilisecond(Date dateToConvert) { + return Instant.ofEpochMilli(dateToConvert.getTime()) + .atZone(ZoneId.systemDefault()) + .toLocalDate(); + } + + public static LocalDate convertToLocalDate(Date dateToConvert) { + return LocalDate.ofInstant(dateToConvert.toInstant(), ZoneId.systemDefault()); + } + +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java b/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java new file mode 100644 index 0000000000..17ca5b1122 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java @@ -0,0 +1,39 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +/** + * Class which shows a way to convert java.util.Date into java.time.LocalDateTime. + * + * @author abialas + * + */ +public class DateToLocalDateTimeConverter { + + public static LocalDateTime convertToLocalDateTimeViaInstant(Date dateToConvert) { + return dateToConvert.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + } + + public static LocalDateTime convertToLocalDateTimeViaSqlTimestamp(Date dateToConvert) { + return new java.sql.Timestamp(dateToConvert.getTime()).toLocalDateTime(); + } + + public static LocalDateTime convertToLocalDateTimeViaMilisecond(Date dateToConvert) { + return Instant.ofEpochMilli(dateToConvert.getTime()) + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + } + + public static LocalDateTime convertToLocalDateTime(Date dateToConvert) { + return LocalDateTime.ofInstant(dateToConvert.toInstant(), ZoneId.systemDefault()); + } + +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java b/core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java new file mode 100644 index 0000000000..f219dcf038 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java @@ -0,0 +1,27 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +/** + * Class which shows different ways of converting java.time.LocalDateTime into java.util.Date. + * + * @author abialas + * + */ +public class LocalDateTimeToDateConverter { + + public static Date convertToDateViaSqlTimestamp(LocalDateTime dateToConvert) { + return java.sql.Timestamp.valueOf(dateToConvert); + } + + public static Date convertToDateViaInstant(LocalDateTime dateToConvert) { + return java.util.Date.from(dateToConvert.atZone(ZoneId.systemDefault()) + .toInstant()); + } + +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java b/core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java new file mode 100644 index 0000000000..f9893da5d0 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java @@ -0,0 +1,28 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; + +/** + * Class which shows different ways of converting java.time.LocalDate into java.util.Date. + * + * @author abialas + * + */ +public class LocalDateToDateConverter { + + public static Date convertToDateViaSqlDate(LocalDate dateToConvert) { + return java.sql.Date.valueOf(dateToConvert); + } + + public static Date convertToDateViaInstant(LocalDate dateToConvert) { + return java.util.Date.from(dateToConvert.atStartOfDay() + .atZone(ZoneId.systemDefault()) + .toInstant()); + } + +} diff --git a/core-java-9/src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java b/core-java-9/src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java new file mode 100644 index 0000000000..de08c2164e --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java @@ -0,0 +1,84 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.baeldung.httpclient; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; +import jdk.incubator.http.HttpClient; +import jdk.incubator.http.HttpRequest; +import jdk.incubator.http.HttpRequest.BodyProcessor; +import jdk.incubator.http.HttpResponse; +import jdk.incubator.http.HttpResponse.BodyHandler; + +/** + * + * @author pkaria + */ +public class HttpClientExample { + + public static void main(String[] args) throws Exception { + httpGetRequest(); + httpPostRequest(); + asynchronousRequest(); + asynchronousMultipleRequests(); + } + + public static void httpGetRequest() throws URISyntaxException, IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + URI httpURI = new URI("http://jsonplaceholder.typicode.com/posts/1"); + HttpRequest request = HttpRequest.newBuilder(httpURI).GET() + .headers("Accept-Enconding", "gzip, deflate").build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandler.asString()); + String responseBody = response.body(); + int responseStatusCode = response.statusCode(); + System.out.println(responseBody); + } + + public static void httpPostRequest() throws URISyntaxException, IOException, InterruptedException { + HttpClient client = HttpClient + .newBuilder() + .build(); + HttpRequest request = HttpRequest + .newBuilder(new URI("http://jsonplaceholder.typicode.com/posts")) + .POST(BodyProcessor.fromString("Sample Post Request")) + .build(); + HttpResponse response + = client.send(request, HttpResponse.BodyHandler.asString()); + String responseBody = response.body(); + System.out.println(responseBody); + } + + public static void asynchronousRequest() throws URISyntaxException { + HttpClient client = HttpClient.newHttpClient(); + URI httpURI = new URI("http://jsonplaceholder.typicode.com/posts/1"); + HttpRequest request = HttpRequest.newBuilder(httpURI).GET().build(); + CompletableFuture> futureResponse = client.sendAsync(request, + HttpResponse.BodyHandler.asString()); + } + + public static void asynchronousMultipleRequests() throws URISyntaxException { + List targets = Arrays.asList(new URI("http://jsonplaceholder.typicode.com/posts/1"), new URI("http://jsonplaceholder.typicode.com/posts/2")); + HttpClient client = HttpClient.newHttpClient(); + List> futures = targets + .stream() + .map(target -> client + .sendAsync( + HttpRequest.newBuilder(target) + .GET() + .build(), + BodyHandler.asFile(Paths.get("base", target.getPath()))) + .thenApply(response -> response.body()) + .thenApply(path -> path.toFile())) + .collect(Collectors.toList()); + } +} diff --git a/core-java-9/src/modules/com.baeldung.httpclient/module-info.java b/core-java-9/src/modules/com.baeldung.httpclient/module-info.java new file mode 100644 index 0000000000..205c9ea725 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.httpclient/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.httpclient { + requires jdk.incubator.httpclient; +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java b/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java new file mode 100644 index 0000000000..ab69bba359 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java @@ -0,0 +1,89 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDate; +import java.time.temporal.ChronoField; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +import com.baeldung.java9.datetime.DateToLocalDateConverter; + +/** + * JUnits for {@link DateToLocalDateConverter} class. + * + * @author abialas + * + */ +public class DateToLocalDateConverterTest { + + @Test + public void shouldReturn10thNovember2010WhenConvertViaInstant() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10); + Date dateToConvert = calendar.getTime(); + + // when + LocalDate localDate = DateToLocalDateConverter.convertToLocalDateViaInstant(dateToConvert); + + // then + assertEquals(2010, localDate.get(ChronoField.YEAR)); + assertEquals(11, localDate.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDate.get(ChronoField.DAY_OF_MONTH)); + } + + @Test + public void shouldReturn10thNovember2010WhenConvertViaMiliseconds() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10); + Date dateToConvert = calendar.getTime(); + + // when + LocalDate localDate = DateToLocalDateConverter.convertToLocalDateViaMilisecond(dateToConvert); + + // then + assertEquals(2010, localDate.get(ChronoField.YEAR)); + assertEquals(11, localDate.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDate.get(ChronoField.DAY_OF_MONTH)); + } + + @Test + public void shouldReturn10thNovember2010WhenConvertViaSqlDate() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10); + Date dateToConvert = calendar.getTime(); + + // when + LocalDate localDate = DateToLocalDateConverter.convertToLocalDateViaSqlDate(dateToConvert); + + // then + assertEquals(2010, localDate.get(ChronoField.YEAR)); + assertEquals(11, localDate.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDate.get(ChronoField.DAY_OF_MONTH)); + } + + @Test + public void shouldReturn10thNovember2010WhenConvertToLocalDate() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10); + Date dateToConvert = calendar.getTime(); + + // when + LocalDate localDateTime = DateToLocalDateConverter.convertToLocalDate(dateToConvert); + + // then + assertEquals(2010, localDateTime.get(ChronoField.YEAR)); + assertEquals(11, localDateTime.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDateTime.get(ChronoField.DAY_OF_MONTH)); + } + +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java b/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java new file mode 100644 index 0000000000..97c70ee5ac --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java @@ -0,0 +1,97 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDateTime; +import java.time.temporal.ChronoField; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +import com.baeldung.java9.datetime.DateToLocalDateTimeConverter; + +/** + * JUnits for {@link DateToLocalDateTimeConverter} class. + * + * @author abialas + * + */ +public class DateToLocalDateTimeConverterTest { + + @Test + public void shouldReturn10thNovember2010time8hour20minWhenConvertViaInstant() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10, 8, 20); + Date dateToConvert = calendar.getTime(); + + // when + LocalDateTime localDateTime = DateToLocalDateTimeConverter.convertToLocalDateTimeViaInstant(dateToConvert); + + // then + assertEquals(2010, localDateTime.get(ChronoField.YEAR)); + assertEquals(11, localDateTime.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDateTime.get(ChronoField.DAY_OF_MONTH)); + assertEquals(8, localDateTime.get(ChronoField.HOUR_OF_DAY)); + assertEquals(20, localDateTime.get(ChronoField.MINUTE_OF_HOUR)); + } + + @Test + public void shouldReturn10thNovember2010time8hour20minWhenConvertViaMiliseconds() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10, 8, 20); + Date dateToConvert = calendar.getTime(); + + // when + LocalDateTime localDateTime = DateToLocalDateTimeConverter.convertToLocalDateTimeViaMilisecond(dateToConvert); + + // then + assertEquals(2010, localDateTime.get(ChronoField.YEAR)); + assertEquals(11, localDateTime.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDateTime.get(ChronoField.DAY_OF_MONTH)); + assertEquals(8, localDateTime.get(ChronoField.HOUR_OF_DAY)); + assertEquals(20, localDateTime.get(ChronoField.MINUTE_OF_HOUR)); + } + + @Test + public void shouldReturn10thNovember2010time8hour20minWhenConvertViaSqlTimestamp() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10, 8, 20); + Date dateToConvert = calendar.getTime(); + + // when + LocalDateTime localDateTime = DateToLocalDateTimeConverter.convertToLocalDateTimeViaSqlTimestamp(dateToConvert); + + // then + assertEquals(2010, localDateTime.get(ChronoField.YEAR)); + assertEquals(11, localDateTime.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDateTime.get(ChronoField.DAY_OF_MONTH)); + assertEquals(8, localDateTime.get(ChronoField.HOUR_OF_DAY)); + assertEquals(20, localDateTime.get(ChronoField.MINUTE_OF_HOUR)); + } + + @Test + public void shouldReturn10thNovember2010time8hour20minWhenConvertToLocalDateTime() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10, 8, 20); + Date dateToConvert = calendar.getTime(); + + // when + LocalDateTime localDateTime = DateToLocalDateTimeConverter.convertToLocalDateTime(dateToConvert); + + // then + assertEquals(2010, localDateTime.get(ChronoField.YEAR)); + assertEquals(11, localDateTime.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDateTime.get(ChronoField.DAY_OF_MONTH)); + assertEquals(8, localDateTime.get(ChronoField.HOUR_OF_DAY)); + assertEquals(20, localDateTime.get(ChronoField.MINUTE_OF_HOUR)); + } + +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterTest.java b/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterTest.java new file mode 100644 index 0000000000..2c6898381f --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterTest.java @@ -0,0 +1,61 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDateTime; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +/** + * + * JUnits for {@link LocalDateTimeToDateConverter} class. + * + * @author abialas + * + */ +public class LocalDateTimeToDateConverterTest { + + @Test + public void shouldReturn10thNovember2010time8hour20minWhenConvertViaInstant() { + // given + LocalDateTime dateToConvert = LocalDateTime.of(2010, 11, 10, 8, 20); + + // when + Date date = LocalDateTimeToDateConverter.convertToDateViaInstant(dateToConvert); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + // then + assertEquals(2010, calendar.get(Calendar.YEAR)); + assertEquals(10, calendar.get(Calendar.MONTH)); + assertEquals(10, calendar.get(Calendar.DAY_OF_MONTH)); + assertEquals(8, calendar.get(Calendar.HOUR)); + assertEquals(20, calendar.get(Calendar.MINUTE)); + assertEquals(0, calendar.get(Calendar.SECOND)); + } + + @Test + public void shouldReturn10thNovember2010WhenConvertViaSqlTimestamp() { + // given + LocalDateTime dateToConvert = LocalDateTime.of(2010, 11, 10, 8, 20); + + // when + Date date = LocalDateTimeToDateConverter.convertToDateViaSqlTimestamp(dateToConvert); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + // then + assertEquals(2010, calendar.get(Calendar.YEAR)); + assertEquals(10, calendar.get(Calendar.MONTH)); + assertEquals(10, calendar.get(Calendar.DAY_OF_MONTH)); + assertEquals(8, calendar.get(Calendar.HOUR)); + assertEquals(20, calendar.get(Calendar.MINUTE)); + assertEquals(0, calendar.get(Calendar.SECOND)); + } + +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterTest.java b/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterTest.java new file mode 100644 index 0000000000..7f20d5d2d2 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterTest.java @@ -0,0 +1,55 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDate; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +/** + * + * JUnits for {@link LocalDateToDateConverter} class. + * + * @author abialas + * + */ +public class LocalDateToDateConverterTest { + + @Test + public void shouldReturn10thNovember2010WhenConvertViaInstant() { + // given + LocalDate dateToConvert = LocalDate.of(2010, 11, 10); + + // when + Date date = LocalDateToDateConverter.convertToDateViaInstant(dateToConvert); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + // then + assertEquals(2010, calendar.get(Calendar.YEAR)); + assertEquals(10, calendar.get(Calendar.MONTH)); + assertEquals(10, calendar.get(Calendar.DAY_OF_MONTH)); + } + + @Test + public void shouldReturn10thNovember2010WhenConvertViaSqlDate() { + // given + LocalDate dateToConvert = LocalDate.of(2010, 11, 10); + + // when + Date date = LocalDateToDateConverter.convertToDateViaSqlDate(dateToConvert); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + // then + assertEquals(2010, calendar.get(Calendar.YEAR)); + assertEquals(10, calendar.get(Calendar.MONTH)); + assertEquals(10, calendar.get(Calendar.DAY_OF_MONTH)); + } + +} diff --git a/core-java-concurrency/README.md b/core-java-concurrency/README.md index f1d95482d4..48c5f2a50c 100644 --- a/core-java-concurrency/README.md +++ b/core-java-concurrency/README.md @@ -30,3 +30,4 @@ - [Guide to Volatile Keyword in Java](http://www.baeldung.com/java-volatile) - [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent) - [Semaphores in Java](http://www.baeldung.com/java-semaphore) +- [Daemon Threads in Java](http://www.baeldung.com/java-daemon-thread) diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java new file mode 100644 index 0000000000..4d87978070 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java @@ -0,0 +1,19 @@ +package com.baeldung.concurrent.daemon; + +public class NewThread extends Thread { + + public void run() { + long startTime = System.currentTimeMillis(); + while (true) { + for (int i = 0; i < 10; i++) { + System.out.println("New Thread is running..." + i); + } + + // prevent the Thread to run forever. It will finish it's execution after 2 seconds + if (System.currentTimeMillis() - startTime > 2000) { + Thread.currentThread().interrupt(); + break; + } + } + } +} diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/executorservice/DelayedCallable.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/executorservice/DelayedCallable.java new file mode 100644 index 0000000000..16d9aa4c9f --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/executorservice/DelayedCallable.java @@ -0,0 +1,39 @@ +package com.baeldung.concurrent.executorservice; + +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; + +public class DelayedCallable implements Callable { + + private String name; + private long period; + private CountDownLatch latch; + + public DelayedCallable(String name, long period, CountDownLatch latch) { + this(name, period); + this.latch = latch; + } + + public DelayedCallable(String name, long period) { + this.name = name; + this.period = period; + } + + public String call() { + + try { + Thread.sleep(period); + + if (latch != null) { + latch.countDown(); + } + + } catch (InterruptedException ex) { + // handle exception + ex.printStackTrace(); + Thread.currentThread().interrupt(); + } + + return name; + } +} diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/stopping/ControlSubThread.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/stopping/ControlSubThread.java new file mode 100644 index 0000000000..0e72821a88 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/stopping/ControlSubThread.java @@ -0,0 +1,52 @@ +package com.baeldung.concurrent.stopping; + +import java.util.concurrent.atomic.AtomicBoolean; + +public class ControlSubThread implements Runnable { + + private Thread worker; + private int interval = 100; + private AtomicBoolean running = new AtomicBoolean(false); + private AtomicBoolean stopped = new AtomicBoolean(true); + + + public ControlSubThread(int sleepInterval) { + interval = sleepInterval; + } + + public void start() { + worker = new Thread(this); + worker.start(); + } + + public void stop() { + running.set(false); + } + + public void interrupt() { + running.set(false); + worker.interrupt(); + } + + boolean isRunning() { + return running.get(); + } + + boolean isStopped() { + return stopped.get(); + } + + public void run() { + running.set(true); + stopped.set(false); + while (running.get()) { + try { + Thread.sleep(interval); + } catch (InterruptedException e) { + // no-op, just loop again + } + // do something + } + stopped.set(true); + } +} diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Data.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Data.java new file mode 100644 index 0000000000..9b850c4153 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Data.java @@ -0,0 +1,33 @@ +package com.baeldung.concurrent.waitandnotify; + +public class Data { + private String packet; + + // True if receiver should wait + // False if sender should wait + private boolean transfer = true; + + public synchronized String receive() { + while (transfer) { + try { + wait(); + } catch (InterruptedException e) {} + } + transfer = true; + + notifyAll(); + return packet; + } + + public synchronized void send(String packet) { + while (!transfer) { + try { + wait(); + } catch (InterruptedException e) {} + } + transfer = false; + + this.packet = packet; + notifyAll(); + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/NetworkDriver.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/NetworkDriver.java new file mode 100644 index 0000000000..d4fd1574c6 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/NetworkDriver.java @@ -0,0 +1,12 @@ +package com.baeldung.concurrent.waitandnotify; + +public class NetworkDriver { + public static void main(String[] args) { + Data data = new Data(); + Thread sender = new Thread(new Sender(data)); + Thread receiver = new Thread(new Receiver(data)); + + sender.start(); + receiver.start(); + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Receiver.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Receiver.java new file mode 100644 index 0000000000..63f48b8031 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Receiver.java @@ -0,0 +1,25 @@ +package com.baeldung.concurrent.waitandnotify; + +import java.util.concurrent.ThreadLocalRandom; + +public class Receiver implements Runnable { + private Data load; + + public Receiver(Data load) { + this.load = load; + } + + public void run() { + for(String receivedMessage = load.receive(); + !"End".equals(receivedMessage) ; + receivedMessage = load.receive()) { + + System.out.println(receivedMessage); + + //Thread.sleep() to mimic heavy server-side processing + try { + Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000)); + } catch (InterruptedException e) {} + } + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Sender.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Sender.java new file mode 100644 index 0000000000..b7d782c3f5 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Sender.java @@ -0,0 +1,30 @@ +package com.baeldung.concurrent.waitandnotify; + +import java.util.concurrent.ThreadLocalRandom; + +public class Sender implements Runnable { + private Data data; + + public Sender(Data data) { + this.data = data; + } + + public void run() { + String packets[] = { + "First packet", + "Second packet", + "Third packet", + "Fourth packet", + "End" + }; + + for (String packet : packets) { + data.send(packet); + + //Thread.sleep() to mimic heavy server-side processing + try { + Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000)); + } catch (InterruptedException e) {} + } + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/daemon/DaemonThreadTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/daemon/DaemonThreadTest.java new file mode 100644 index 0000000000..3ca69d8847 --- /dev/null +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/daemon/DaemonThreadTest.java @@ -0,0 +1,31 @@ +package com.baeldung.concurrent.daemon; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Ignore; +import org.junit.Test; + +public class DaemonThreadTest { + + @Test + @Ignore + public void whenCallIsDaemon_thenCorrect() { + NewThread daemonThread = new NewThread(); + NewThread userThread = new NewThread(); + daemonThread.setDaemon(true); + daemonThread.start(); + userThread.start(); + + assertTrue(daemonThread.isDaemon()); + assertFalse(userThread.isDaemon()); + } + + @Test(expected = IllegalThreadStateException.class) + @Ignore + public void givenUserThread_whenSetDaemonWhileRunning_thenIllegalThreadStateException() { + NewThread daemonThread = new NewThread(); + daemonThread.start(); + daemonThread.setDaemon(true); + } +} diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java new file mode 100644 index 0000000000..7e2bf590fd --- /dev/null +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java @@ -0,0 +1,207 @@ +package com.baeldung.concurrent.executorservice; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.*; + +import static junit.framework.TestCase.assertTrue; + +public class WaitingForThreadsToFinishTest { + + private static final Logger LOG = LoggerFactory.getLogger(WaitingForThreadsToFinishTest.class); + private final static ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10); + + public void awaitTerminationAfterShutdown(ExecutorService threadPool) { + threadPool.shutdown(); + try { + if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) { + threadPool.shutdownNow(); + } + } catch (InterruptedException ex) { + threadPool.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + + @Test + public void givenMultipleThreads_whenUsingCountDownLatch_thenMainShoudWaitForAllToFinish() { + + ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10); + + try { + long startTime = System.currentTimeMillis(); + + // create a CountDownLatch that waits for the 2 threads to finish + CountDownLatch latch = new CountDownLatch(2); + + for (int i = 0; i < 2; i++) { + WORKER_THREAD_POOL.submit(() -> { + try { + Thread.sleep(1000); + latch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + Thread.currentThread().interrupt(); + } + }); + } + + // wait for the latch to be decremented by the two threads + latch.await(); + + long processingTime = System.currentTimeMillis() - startTime; + assertTrue(processingTime >= 1000); + + } catch (InterruptedException e) { + e.printStackTrace(); + } + + awaitTerminationAfterShutdown(WORKER_THREAD_POOL); + } + + @Test + public void givenMultipleThreads_whenInvokeAll_thenMainThreadShouldWaitForAllToFinish() { + + ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10); + + List> callables = Arrays.asList( + new DelayedCallable("fast thread", 100), + new DelayedCallable("slow thread", 3000)); + + try { + long startProcessingTime = System.currentTimeMillis(); + List> futures = WORKER_THREAD_POOL.invokeAll(callables); + + awaitTerminationAfterShutdown(WORKER_THREAD_POOL); + + try { + WORKER_THREAD_POOL.submit((Callable) () -> { + Thread.sleep(1000000); + return null; + }); + } catch (RejectedExecutionException ex) { + // + } + + long totalProcessingTime = System.currentTimeMillis() - startProcessingTime; + assertTrue(totalProcessingTime >= 3000); + + String firstThreadResponse = futures.get(0) + .get(); + assertTrue("First response should be from the fast thread", "fast thread".equals(firstThreadResponse)); + + String secondThreadResponse = futures.get(1) + .get(); + assertTrue("Last response should be from the slow thread", "slow thread".equals(secondThreadResponse)); + + } catch (ExecutionException | InterruptedException ex) { + ex.printStackTrace(); + } + } + + @Test + public void givenMultipleThreads_whenUsingCompletionService_thenMainThreadShouldWaitForAllToFinish() { + + CompletionService service = new ExecutorCompletionService<>(WORKER_THREAD_POOL); + + List> callables = Arrays.asList( + new DelayedCallable("fast thread", 100), + new DelayedCallable("slow thread", 3000)); + + for (Callable callable : callables) { + service.submit(callable); + } + + try { + + long startProcessingTime = System.currentTimeMillis(); + + Future future = service.take(); + String firstThreadResponse = future.get(); + long totalProcessingTime = System.currentTimeMillis() - startProcessingTime; + + assertTrue("First response should be from the fast thread", "fast thread".equals(firstThreadResponse)); + assertTrue(totalProcessingTime >= 100 && totalProcessingTime < 1000); + LOG.debug("Thread finished after: " + totalProcessingTime + " milliseconds"); + + future = service.take(); + String secondThreadResponse = future.get(); + totalProcessingTime = System.currentTimeMillis() - startProcessingTime; + + assertTrue("Last response should be from the slow thread", "slow thread".equals(secondThreadResponse)); + assertTrue(totalProcessingTime >= 3000 && totalProcessingTime < 4000); + LOG.debug("Thread finished after: " + totalProcessingTime + " milliseconds"); + + } catch (ExecutionException | InterruptedException ex) { + ex.printStackTrace(); + } finally { + awaitTerminationAfterShutdown(WORKER_THREAD_POOL); + } + } + + @Test + public void givenMultipleThreads_whenUsingCompletableFutures_thenMainThreadShouldWaitForAllToFinish() { + + CompletableFuture future1 = CompletableFuture.supplyAsync(() -> { + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return "Hello"; + }); + + CompletableFuture future2 = CompletableFuture.supplyAsync(() -> { + + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return "Beautiful"; + }); + + CompletableFuture future3 = CompletableFuture.supplyAsync(() -> { + + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return "World"; + }); + + long startProcessingTime = System.currentTimeMillis(); + CompletableFuture combinedFuture = CompletableFuture.allOf(future1, future2, future3); + combinedFuture.join(); + + long totalProcessingTime = System.currentTimeMillis() - startProcessingTime; + assertTrue(totalProcessingTime >= 5000 && totalProcessingTime < 6000); + + LOG.debug("Responses from all threads are available after " + totalProcessingTime + " milliseconds"); + + try { + String thread1Response = future1.get(); + assertTrue(thread1Response.equals("Hello")); + + String thread2Response = future2.get(); + assertTrue(thread2Response.equals("Beautiful")); + + String thread3Response = future3.get(); + assertTrue(thread3Response.equals("World")); + + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + + awaitTerminationAfterShutdown(WORKER_THREAD_POOL); + } +} diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/runnable/RunnableVsThreadLiveTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/runnable/RunnableVsThreadLiveTest.java new file mode 100644 index 0000000000..2a51f83e2b --- /dev/null +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/runnable/RunnableVsThreadLiveTest.java @@ -0,0 +1,133 @@ +package com.baeldung.concurrent.runnable; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.apache.commons.lang3.RandomUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RunnableVsThreadLiveTest { + + private static Logger log = + LoggerFactory.getLogger(RunnableVsThreadLiveTest.class); + + private static ExecutorService executorService; + + @BeforeClass + public static void setup() { + executorService = Executors.newCachedThreadPool(); + } + + @Test + public void givenARunnable_whenRunIt_thenResult() throws Exception{ + Thread thread = new Thread(new SimpleRunnable( + "SimpleRunnable executed using Thread")); + thread.start(); + thread.join(); + } + + @Test + public void givenARunnable_whenSubmitToES_thenResult() throws Exception{ + + executorService.submit(new SimpleRunnable( + "SimpleRunnable executed using ExecutorService")).get(); + } + + @Test + public void givenARunnableLambda_whenSubmitToES_thenResult() + throws Exception{ + + executorService.submit(()-> + log.info("Lambda runnable executed!!!")).get(); + } + + @Test + public void givenAThread_whenRunIt_thenResult() throws Exception{ + Thread thread = new SimpleThread( + "SimpleThread executed using Thread"); + thread.start(); + thread.join(); + } + + @Test + public void givenAThread_whenSubmitToES_thenResult() throws Exception{ + + executorService.submit(new SimpleThread( + "SimpleThread executed using ExecutorService")).get(); + } + + @Test + public void givenACallable_whenSubmitToES_thenResult() throws Exception { + + Future future = executorService.submit( + new SimpleCallable()); + log.info("Result from callable: {}", future.get()); + } + + @Test + public void givenACallableAsLambda_whenSubmitToES_thenResult() + throws Exception { + + Future future = executorService.submit(() -> RandomUtils.nextInt(0, 100)); + + log.info("Result from callable: {}", future.get()); + } + + @AfterClass + public static void tearDown() { + if ( executorService != null && !executorService.isShutdown()) { + executorService.shutdown(); + } + } +} + +class SimpleThread extends Thread{ + + private static final Logger log = + LoggerFactory.getLogger(SimpleThread.class); + + private String message; + + SimpleThread(String message) { + this.message = message; + } + + @Override + public void run() { + log.info(message); + } +} + +class SimpleRunnable implements Runnable { + + private static final Logger log = + LoggerFactory.getLogger(SimpleRunnable.class); + + private String message; + + SimpleRunnable(String message) { + this.message = message; + } + + + @Override + public void run() { + log.info(message); + } +} + +class SimpleCallable implements Callable { + + @Override + public Integer call() throws Exception { + return RandomUtils.nextInt(0, 100); + } + +} + diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java new file mode 100644 index 0000000000..70854f013f --- /dev/null +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java @@ -0,0 +1,54 @@ +package com.baeldung.concurrent.stopping; + +import com.jayway.awaitility.Awaitility; +import org.junit.Test; + +import java.util.concurrent.TimeUnit; + +import static com.jayway.awaitility.Awaitility.await; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class StopThreadTest { + + @Test + public void whenStoppedThreadIsStopped() throws InterruptedException { + + int interval = 100; + + ControlSubThread controlSubThread = new ControlSubThread(interval); + controlSubThread.start(); + + // Give things a chance to get set up + Thread.sleep(interval); + assertTrue(controlSubThread.isRunning()); + assertFalse(controlSubThread.isStopped()); + + // Stop it and make sure the flags have been reversed + controlSubThread.stop(); + await() + .until(() -> assertTrue(controlSubThread.isStopped())); + } + + @Test + public void whenInterruptedThreadIsStopped() throws InterruptedException { + + int interval = 5000; + + ControlSubThread controlSubThread = new ControlSubThread(interval); + controlSubThread.start(); + + // Give things a chance to get set up + Thread.sleep(100); + assertTrue(controlSubThread.isRunning()); + assertFalse(controlSubThread.isStopped()); + + // Stop it and make sure the flags have been reversed + controlSubThread.interrupt(); + + // Wait less than the time we would normally sleep, and make sure we exited. + Awaitility.await() + .atMost(interval/ 10, TimeUnit.MILLISECONDS) + .until(controlSubThread::isStopped); + } +} diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/synchronize/BaeldungSychronizedBlockTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/synchronize/BaeldungSychronizedBlockTest.java index 1f8e8d681a..9c56fa64be 100644 --- a/core-java-concurrency/src/test/java/com/baeldung/concurrent/synchronize/BaeldungSychronizedBlockTest.java +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/synchronize/BaeldungSychronizedBlockTest.java @@ -18,7 +18,7 @@ public class BaeldungSychronizedBlockTest { IntStream.range(0, 1000) .forEach(count -> service.submit(synchronizedBlocks::performSynchronisedTask)); - service.awaitTermination(100, TimeUnit.MILLISECONDS); + service.awaitTermination(500, TimeUnit.MILLISECONDS); assertEquals(1000, synchronizedBlocks.getCount()); } @@ -29,7 +29,7 @@ public class BaeldungSychronizedBlockTest { IntStream.range(0, 1000) .forEach(count -> service.submit(BaeldungSynchronizedBlocks::performStaticSyncTask)); - service.awaitTermination(100, TimeUnit.MILLISECONDS); + service.awaitTermination(500, TimeUnit.MILLISECONDS); assertEquals(1000, BaeldungSynchronizedBlocks.getStaticCount()); } diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/waitandnotify/NetworkIntegrationTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/waitandnotify/NetworkIntegrationTest.java new file mode 100644 index 0000000000..49f4313e9d --- /dev/null +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/waitandnotify/NetworkIntegrationTest.java @@ -0,0 +1,65 @@ +package com.baeldung.concurrent.waitandnotify; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class NetworkIntegrationTest { + + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final ByteArrayOutputStream errContent = new ByteArrayOutputStream(); + private String expected; + + @Before + public void setUpStreams() { + System.setOut(new PrintStream(outContent)); + System.setErr(new PrintStream(errContent)); + } + + @Before + public void setUpExpectedOutput() { + StringWriter expectedStringWriter = new StringWriter(); + + PrintWriter printWriter = new PrintWriter(expectedStringWriter); + printWriter.println("First packet"); + printWriter.println("Second packet"); + printWriter.println("Third packet"); + printWriter.println("Fourth packet"); + printWriter.close(); + + expected = expectedStringWriter.toString(); + } + + @After + public void cleanUpStreams() { + System.setOut(null); + System.setErr(null); + } + + @Test + public void givenSenderAndReceiver_whenSendingPackets_thenNetworkSynchronized() { + Data data = new Data(); + Thread sender = new Thread(new Sender(data)); + Thread receiver = new Thread(new Receiver(data)); + + sender.start(); + receiver.start(); + + //wait for sender and receiver to finish before we test against expected + try { + sender.join(); + receiver.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + assertEquals(expected, outContent.toString()); + } +} diff --git a/core-java-sun/.gitignore b/core-java-sun/.gitignore new file mode 100644 index 0000000000..3de4cc647e --- /dev/null +++ b/core-java-sun/.gitignore @@ -0,0 +1,26 @@ +*.class + +0.* + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* +.resourceCache + +# Packaged files # +*.jar +*.war +*.ear + +# Files generated by integration tests +*.txt +backup-pom.xml +/bin/ +/temp + +#IntelliJ specific +.idea/ +*.iml \ No newline at end of file diff --git a/core-java-sun/README.md b/core-java-sun/README.md new file mode 100644 index 0000000000..9cf8b26f1b --- /dev/null +++ b/core-java-sun/README.md @@ -0,0 +1,6 @@ +========= + +## Core Java Cookbooks and Examples + +### Relevant Articles: +- [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) diff --git a/core-java-sun/pom.xml b/core-java-sun/pom.xml new file mode 100644 index 0000000000..3997f47d19 --- /dev/null +++ b/core-java-sun/pom.xml @@ -0,0 +1,489 @@ + + 4.0.0 + com.baeldung + core-java-sun + 0.1.0-SNAPSHOT + jar + + core-java-sun + + + + + + net.sourceforge.collections + collections-generic + ${collections-generic.version} + + + com.google.guava + guava + ${guava.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + commons-io + commons-io + ${commons-io.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + + org.decimal4j + decimal4j + ${decimal4j.version} + + + + org.bouncycastle + bcprov-jdk15on + ${bouncycastle.version} + + + + org.unix4j + unix4j-command + ${unix4j.version} + + + + com.googlecode.grep4j + grep4j + ${grep4j.version} + + + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + + log4j + log4j + 1.2.17 + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + + org.hamcrest + hamcrest-all + 1.3 + test + + + + junit + junit + ${junit.version} + test + + + + org.hamcrest + hamcrest-core + ${org.hamcrest.version} + test + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + org.mockito + mockito-core + ${mockito.version} + test + + + com.jayway.awaitility + awaitility + ${avaitility.version} + test + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + org.javamoney + moneta + 1.1 + + + + org.owasp.esapi + esapi + 2.1.0.1 + + + + com.sun.messaging.mq + fscontext + ${fscontext.version} + + + com.codepoetics + protonpack + ${protonpack.version} + + + one.util + streamex + ${streamex.version} + + + io.vavr + vavr + ${vavr.version} + + + org.openjdk.jmh + jmh-core + 1.19 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.19 + + + org.springframework + spring-web + 4.3.4.RELEASE + + + com.sun + tools + 1.8.0 + system + ${java.home}/../lib/tools.jar + + + + + core-java + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*LiveTest.java + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/libs + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + org.baeldung.executable.ExecutableMavenJar + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + ${project.basedir} + + + org.baeldung.executable.ExecutableMavenJar + + + + jar-with-dependencies + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + shade + + + true + + + org.baeldung.executable.ExecutableMavenJar + + + + + + + + + com.jolira + onejar-maven-plugin + + + + org.baeldung.executable.ExecutableMavenJar + true + ${project.build.finalName}-onejar.${project.packaging} + + + one-jar + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + spring-boot + org.baeldung.executable.ExecutableMavenJar + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + java + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + -Xmx300m + -XX:+UseParallelGC + -classpath + + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + + + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + org.codehaus.mojo + exec-maven-plugin + + + + run-benchmarks + + none + + exec + + + test + java + + -classpath + + org.openjdk.jmh.Main + .* + + + + + + + + + + + + + 2.8.5 + + + 1.7.21 + 1.1.7 + + + 23.0 + 3.5 + 1.55 + 1.10 + 3.6.1 + 1.0.3 + 2.5 + 4.1 + 4.01 + 0.4 + 1.8.7 + 1.16.12 + 4.6-b01 + 1.13 + 0.6.5 + 0.9.0 + + + 1.3 + 4.12 + 2.8.9 + 3.6.1 + 1.7.0 + + + 3.6.0 + 2.19.1 + + \ No newline at end of file diff --git a/mockito/.gitignore b/core-java-sun/src/main/java/com/baeldung/.gitignore similarity index 100% rename from mockito/.gitignore rename to core-java-sun/src/main/java/com/baeldung/.gitignore diff --git a/core-java-sun/src/main/java/com/baeldung/README.md b/core-java-sun/src/main/java/com/baeldung/README.md new file mode 100644 index 0000000000..51809b2882 --- /dev/null +++ b/core-java-sun/src/main/java/com/baeldung/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [SHA-256 Hashing in Java](http://www.baeldung.com/sha-256-hashing-java) diff --git a/core-java-sun/src/main/java/com/baeldung/javac/Positive.java b/core-java-sun/src/main/java/com/baeldung/javac/Positive.java new file mode 100644 index 0000000000..443b866fea --- /dev/null +++ b/core-java-sun/src/main/java/com/baeldung/javac/Positive.java @@ -0,0 +1,9 @@ +package com.baeldung.javac; + +import java.lang.annotation.*; + +@Documented +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.PARAMETER}) +public @interface Positive { +} diff --git a/core-java-sun/src/main/java/com/baeldung/javac/SampleJavacPlugin.java b/core-java-sun/src/main/java/com/baeldung/javac/SampleJavacPlugin.java new file mode 100644 index 0000000000..eb48d6a216 --- /dev/null +++ b/core-java-sun/src/main/java/com/baeldung/javac/SampleJavacPlugin.java @@ -0,0 +1,123 @@ +package com.baeldung.javac; + +import com.sun.source.tree.MethodTree; +import com.sun.source.tree.VariableTree; +import com.sun.source.util.*; +import com.sun.tools.javac.api.BasicJavacTask; +import com.sun.tools.javac.code.TypeTag; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Name; +import com.sun.tools.javac.util.Names; + +import javax.tools.JavaCompiler; +import java.util.*; +import java.util.stream.Collectors; + +import static com.sun.tools.javac.util.List.nil; + +/** + * A {@link JavaCompiler javac} plugin which inserts {@code >= 0} checks into resulting {@code *.class} files + * for numeric method parameters marked by {@link Positive} + */ +public class SampleJavacPlugin implements Plugin { + + public static final String NAME = "MyPlugin"; + + private static Set TARGET_TYPES = new HashSet<>(Arrays.asList( + // Use only primitive types for simplicity + byte.class.getName(), short.class.getName(), char.class.getName(), + int.class.getName(), long.class.getName(), float.class.getName(), double.class.getName())); + + @Override + public String getName() { + return NAME; + } + + @Override + public void init(JavacTask task, String... args) { + Context context = ((BasicJavacTask) task).getContext(); + task.addTaskListener(new TaskListener() { + @Override + public void started(TaskEvent e) { + } + + @Override + public void finished(TaskEvent e) { + if (e.getKind() != TaskEvent.Kind.PARSE) { + return; + } + e.getCompilationUnit() + .accept(new TreeScanner() { + @Override + public Void visitMethod(MethodTree method, Void v) { + List parametersToInstrument = method.getParameters() + .stream() + .filter(SampleJavacPlugin.this::shouldInstrument) + .collect(Collectors.toList()); + if (!parametersToInstrument.isEmpty()) { + // There is a possible case that more than one argument is marked by @Positive, + // as the checks are added to the method's body beginning, we process parameters RTL + // to ensure correct order. + Collections.reverse(parametersToInstrument); + parametersToInstrument.forEach(p -> addCheck(method, p, context)); + } + // There is a possible case that there is a nested class declared in a method's body, + // hence, we want to proceed with method body AST as well. + return super.visitMethod(method, v); + } + }, null); + } + }); + } + + private boolean shouldInstrument(VariableTree parameter) { + return TARGET_TYPES.contains(parameter.getType().toString()) + && parameter.getModifiers().getAnnotations() + .stream() + .anyMatch(a -> Positive.class.getSimpleName().equals(a.getAnnotationType().toString())); + } + + private void addCheck(MethodTree method, VariableTree parameter, Context context) { + JCTree.JCIf check = createCheck(parameter, context); + JCTree.JCBlock body = (JCTree.JCBlock) method.getBody(); + body.stats = body.stats.prepend(check); + } + + private static JCTree.JCIf createCheck(VariableTree parameter, Context context) { + TreeMaker factory = TreeMaker.instance(context); + Names symbolsTable = Names.instance(context); + + return factory.at(((JCTree) parameter).pos) + .If(factory.Parens(createIfCondition(factory, symbolsTable, parameter)), + createIfBlock(factory, symbolsTable, parameter), + null); + } + + private static JCTree.JCBinary createIfCondition(TreeMaker factory, Names symbolsTable, VariableTree parameter) { + Name parameterId = symbolsTable.fromString(parameter.getName().toString()); + return factory.Binary(JCTree.Tag.LE, + factory.Ident(parameterId), + factory.Literal(TypeTag.INT, 0)); + } + + private static JCTree.JCBlock createIfBlock(TreeMaker factory, Names symbolsTable, VariableTree parameter) { + String parameterName = parameter.getName().toString(); + Name parameterId = symbolsTable.fromString(parameterName); + + String errorMessagePrefix = String.format("Argument '%s' of type %s is marked by @%s but got '", + parameterName, parameter.getType(), Positive.class.getSimpleName()); + String errorMessageSuffix = "' for it"; + + return factory.Block(0, com.sun.tools.javac.util.List.of( + factory.Throw( + factory.NewClass(null, nil(), + factory.Ident(symbolsTable.fromString(IllegalArgumentException.class.getSimpleName())), + com.sun.tools.javac.util.List.of(factory.Binary(JCTree.Tag.PLUS, + factory.Binary(JCTree.Tag.PLUS, factory.Literal(TypeTag.CLASS, errorMessagePrefix), + factory.Ident(parameterId)), + factory.Literal(TypeTag.CLASS, errorMessageSuffix))), null)))); + } + +} diff --git a/core-java-sun/src/main/resources/log4j.properties b/core-java-sun/src/main/resources/log4j.properties new file mode 100644 index 0000000000..621cf01735 --- /dev/null +++ b/core-java-sun/src/main/resources/log4j.properties @@ -0,0 +1,6 @@ +log4j.rootLogger=DEBUG, A1 + +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file diff --git a/couchbase-sdk/src/main/resources/logback.xml b/core-java-sun/src/main/resources/logback.xml similarity index 100% rename from couchbase-sdk/src/main/resources/logback.xml rename to core-java-sun/src/main/resources/logback.xml diff --git a/core-java-sun/src/test/java/com/baeldung/javac/SampleJavacPluginIntegrationTest.java b/core-java-sun/src/test/java/com/baeldung/javac/SampleJavacPluginIntegrationTest.java new file mode 100644 index 0000000000..b877038add --- /dev/null +++ b/core-java-sun/src/test/java/com/baeldung/javac/SampleJavacPluginIntegrationTest.java @@ -0,0 +1,42 @@ +package com.baeldung.javac; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SampleJavacPluginIntegrationTest { + + private static final String CLASS_TEMPLATE = + "package com.baeldung.javac;\n" + + "\n" + + "public class Test {\n" + + " public static %1$s service(@Positive %1$s i) {\n" + + " return i;\n" + + " }\n" + + "}\n" + + ""; + + private TestCompiler compiler = new TestCompiler(); + private TestRunner runner = new TestRunner(); + + @Test(expected = IllegalArgumentException.class) + public void givenInt_whenNegative_thenThrowsException() throws Throwable { + compileAndRun(double.class,-1); + } + + @Test(expected = IllegalArgumentException.class) + public void givenInt_whenZero_thenThrowsException() throws Throwable { + compileAndRun(int.class,0); + } + + @Test + public void givenInt_whenPositive_thenSuccess() throws Throwable { + assertEquals(1, compileAndRun(int.class, 1)); + } + + private Object compileAndRun(Class argumentType, Object argument) throws Throwable { + String qualifiedClassName = "com.baeldung.javac.Test"; + byte[] byteCode = compiler.compile(qualifiedClassName, String.format(CLASS_TEMPLATE, argumentType.getName())); + return runner.run(byteCode, qualifiedClassName, "service", new Class[] {argumentType}, argument); + } +} diff --git a/core-java-sun/src/test/java/com/baeldung/javac/SimpleClassFile.java b/core-java-sun/src/test/java/com/baeldung/javac/SimpleClassFile.java new file mode 100644 index 0000000000..2c8e66e6e3 --- /dev/null +++ b/core-java-sun/src/test/java/com/baeldung/javac/SimpleClassFile.java @@ -0,0 +1,26 @@ +package com.baeldung.javac; + +import javax.tools.SimpleJavaFileObject; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URI; + +/** Holds compiled byte code in a byte array */ +public class SimpleClassFile extends SimpleJavaFileObject { + + private ByteArrayOutputStream out; + + public SimpleClassFile(URI uri) { + super(uri, Kind.CLASS); + } + + @Override + public OutputStream openOutputStream() throws IOException { + return out = new ByteArrayOutputStream(); + } + + public byte[] getCompiledBinaries() { + return out.toByteArray(); + } +} \ No newline at end of file diff --git a/core-java-sun/src/test/java/com/baeldung/javac/SimpleFileManager.java b/core-java-sun/src/test/java/com/baeldung/javac/SimpleFileManager.java new file mode 100644 index 0000000000..346f240754 --- /dev/null +++ b/core-java-sun/src/test/java/com/baeldung/javac/SimpleFileManager.java @@ -0,0 +1,34 @@ +package com.baeldung.javac; + +import javax.tools.*; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +/** Adapts {@link SimpleClassFile} to the {@link JavaCompiler} */ +public class SimpleFileManager extends ForwardingJavaFileManager { + + private final List compiled = new ArrayList<>(); + + public SimpleFileManager(StandardJavaFileManager delegate) { + super(delegate); + } + + @Override + public JavaFileObject getJavaFileForOutput(Location location, + String className, + JavaFileObject.Kind kind, + FileObject sibling) + { + SimpleClassFile result = new SimpleClassFile(URI.create("string://" + className)); + compiled.add(result); + return result; + } + + /** + * @return compiled binaries processed by the current class + */ + public List getCompiled() { + return compiled; + } +} \ No newline at end of file diff --git a/core-java-sun/src/test/java/com/baeldung/javac/SimpleSourceFile.java b/core-java-sun/src/test/java/com/baeldung/javac/SimpleSourceFile.java new file mode 100644 index 0000000000..9287b1a0dd --- /dev/null +++ b/core-java-sun/src/test/java/com/baeldung/javac/SimpleSourceFile.java @@ -0,0 +1,23 @@ +package com.baeldung.javac; + +import javax.tools.SimpleJavaFileObject; +import java.net.URI; + +/** Exposes given test source to the compiler. */ +public class SimpleSourceFile extends SimpleJavaFileObject { + + private final String content; + + public SimpleSourceFile(String qualifiedClassName, String testSource) { + super(URI.create(String.format("file://%s%s", + qualifiedClassName.replaceAll("\\.", "/"), + Kind.SOURCE.extension)), + Kind.SOURCE); + content = testSource; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return content; + } +} \ No newline at end of file diff --git a/core-java-sun/src/test/java/com/baeldung/javac/TestCompiler.java b/core-java-sun/src/test/java/com/baeldung/javac/TestCompiler.java new file mode 100644 index 0000000000..ee40e563a3 --- /dev/null +++ b/core-java-sun/src/test/java/com/baeldung/javac/TestCompiler.java @@ -0,0 +1,35 @@ +package com.baeldung.javac; + +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; + +public class TestCompiler { + public byte[] compile(String qualifiedClassName, String testSource) { + StringWriter output = new StringWriter(); + + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + SimpleFileManager fileManager = new SimpleFileManager(compiler.getStandardFileManager( + null, + null, + null + )); + List compilationUnits = singletonList(new SimpleSourceFile(qualifiedClassName, testSource)); + List arguments = new ArrayList<>(); + arguments.addAll(asList("-classpath", System.getProperty("java.class.path"), + "-Xplugin:" + SampleJavacPlugin.NAME)); + JavaCompiler.CompilationTask task = compiler.getTask(output, + fileManager, + null, + arguments, + null, + compilationUnits); + task.call(); + return fileManager.getCompiled().iterator().next().getCompiledBinaries(); + } +} diff --git a/core-java-sun/src/test/java/com/baeldung/javac/TestRunner.java b/core-java-sun/src/test/java/com/baeldung/javac/TestRunner.java new file mode 100644 index 0000000000..6a03ad4918 --- /dev/null +++ b/core-java-sun/src/test/java/com/baeldung/javac/TestRunner.java @@ -0,0 +1,41 @@ +package com.baeldung.javac; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class TestRunner { + + public Object run(byte[] byteCode, + String qualifiedClassName, + String methodName, + Class[] argumentTypes, + Object... args) + throws Throwable + { + ClassLoader classLoader = new ClassLoader() { + @Override + protected Class findClass(String name) throws ClassNotFoundException { + return defineClass(name, byteCode, 0, byteCode.length); + } + }; + Class clazz; + try { + clazz = classLoader.loadClass(qualifiedClassName); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Can't load compiled test class", e); + } + + Method method; + try { + method = clazz.getMethod(methodName, argumentTypes); + } catch (NoSuchMethodException e) { + throw new RuntimeException("Can't find the 'main()' method in the compiled test class", e); + } + + try { + return method.invoke(null, args); + } catch (InvocationTargetException e) { + throw e.getCause(); + } + } +} diff --git a/spring-hibernate3/.gitignore b/core-java-sun/src/test/resources/.gitignore similarity index 100% rename from spring-hibernate3/.gitignore rename to core-java-sun/src/test/resources/.gitignore diff --git a/core-java/README.md b/core-java/README.md index 57457e90fe..8287a21d1e 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -99,4 +99,26 @@ - [ClassNotFoundException vs NoClassDefFoundError](http://www.baeldung.com/java-classnotfoundexception-and-noclassdeffounderror) - [Guide to UUID in Java](http://www.baeldung.com/java-uuid) - [Guide to Escaping Characters in Java RegExps](http://www.baeldung.com/java-regexp-escape-char) +- [Guide to hashCode() in Java](http://www.baeldung.com/java-hashcode) +- [Collect a Java Stream to an Immutable Collection](http://www.baeldung.com/java-stream-immutable-collection) +- [Difference between URL and URI](http://www.baeldung.com/java-url-vs-uri) +- [Broadcasting and Multicasting in Java](http://www.baeldung.com/java-broadcast-multicast) +- [Converting a List to String in Java](http://www.baeldung.com/java-list-to-string) +- [CharSequence vs. String in Java](http://www.baeldung.com/java-char-sequence-string) - [Period and Duration in Java](http://www.baeldung.com/java-period-duration) +- [Guide to the Diamond Operator in Java](http://www.baeldung.com/java-diamond-operator) +- [Singletons in Java](http://www.baeldung.com/java-singleton) +- [“Sneaky Throws” in Java](http://www.baeldung.com/java-sneaky-throws) +- [OutOfMemoryError: GC Overhead Limit Exceeded](http://www.baeldung.com/java-gc-overhead-limit-exceeded) +- [How to Iterate Over a Stream With Indices](http://www.baeldung.com/java-stream-indices) +- [StringBuilder and StringBuffer in Java](http://www.baeldung.com/java-string-builder-string-buffer) +- [Number of Digits in an Integer in Java](http://www.baeldung.com/java-number-of-digits-in-int) +- [Proxy, Decorator, Adapter and Bridge Patterns](http://www.baeldung.com/java-structural-design-patterns) +- [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) +- [A Guide to the Static Keyword in Java](http://www.baeldung.com/java-static) +- [Initializing Arrays in Java](http://www.baeldung.com/java-initialize-array) +- [Guide to Java String Pool](http://www.baeldung.com/java-string-pool) +- [Copy a File with Java](http://www.baeldung.com/java-copy-file) +- [Introduction to Creational Design Patterns](http://www.baeldung.com/creational-design-patterns) +- [Quick Example - Comparator vs Comparable in Java](http://www.baeldung.com/java-comparator-comparable) + diff --git a/core-java/customers.xml b/core-java/customers.xml new file mode 100644 index 0000000000..b52dc27633 --- /dev/null +++ b/core-java/customers.xml @@ -0,0 +1,95 @@ + + + + SELECT * FROM customers + 1008 + + true + 1000 + 0 + 2 + + + + + 0 + 0 + 0 + true + ResultSet.TYPE_SCROLL_INSENSITIVE + false + customers + jdbc:h2:mem:testdb + + com.sun.rowset.providers.RIOptimisticProvider + Oracle Corporation + 1.0 + 2 + 1 + + + + 2 + + 1 + false + true + false + 0 + true + true + 11 + ID + ID + PUBLIC + 10 + 0 + CUSTOMERS + TESTDB + 4 + INTEGER + + + 2 + false + true + false + 0 + true + true + 50 + NAME + NAME + PUBLIC + 50 + 0 + CUSTOMERS + TESTDB + 12 + VARCHAR + + + + + 1 + Customer1 + + + 2 + Customer2 + + + 3 + Customer3 + + + 4 + Customer4 + + + 5 + Customer5 + + + diff --git a/core-java/src/main/java/com/baeldung/array/ArrayInitializer.java b/core-java/src/main/java/com/baeldung/array/ArrayInitializer.java new file mode 100644 index 0000000000..0ba6c342d9 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/array/ArrayInitializer.java @@ -0,0 +1,78 @@ +package com.baeldung.array; + +import java.util.Arrays; + +import org.apache.commons.lang.ArrayUtils; + +public class ArrayInitializer { + + static int[] initializeArrayInLoop() { + int array[] = new int[5]; + for (int i = 0; i < array.length; i++) { + array[i] = i + 2; + } + return array; + } + + static int[][] initializeMultiDimensionalArrayInLoop() { + int array[][] = new int[2][5]; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 5; j++) { + array[i][j] = j + 1; + } + } + + return array; + } + + static String[] initializeArrayAtTimeOfDeclarationMethod1() { + String array[] = new String[] { "Toyota", "Mercedes", "BMW", "Volkswagen", "Skoda" }; + return array; + } + + static int[] initializeArrayAtTimeOfDeclarationMethod2() { + int[] array = new int[] { 1, 2, 3, 4, 5 }; + return array; + } + + static int[] initializeArrayAtTimeOfDeclarationMethod3() { + int array[] = { 1, 2, 3, 4, 5 }; + return array; + } + + static long[] initializeArrayUsingArraysFill() { + long array[] = new long[5]; + Arrays.fill(array, 30); + return array; + } + + static int[] initializeArrayRangeUsingArraysFill() { + int array[] = new int[5]; + Arrays.fill(array, 0, 3, -50); + return array; + } + + static int[] initializeArrayUsingArraysCopy() { + int array[] = { 1, 2, 3, 4, 5 }; + int[] copy = Arrays.copyOf(array, 5); + return copy; + } + + static int[] initializeLargerArrayUsingArraysCopy() { + int array[] = { 1, 2, 3, 4, 5 }; + int[] copy = Arrays.copyOf(array, 6); + return copy; + } + + static int[] initializeArrayUsingArraysSetAll() { + int[] array = new int[20]; + + Arrays.setAll(array, p -> p > 9 ? 0 : p); + return array; + } + + static char[] initializeArrayUsingArraysUtilClone() { + char[] array = new char[] { 'a', 'b', 'c' }; + return ArrayUtils.clone(array); + } +} diff --git a/core-java/src/main/java/com/baeldung/breakcontinue/BreakContinue.java b/core-java/src/main/java/com/baeldung/breakcontinue/BreakContinue.java new file mode 100644 index 0000000000..ce85b487c1 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/breakcontinue/BreakContinue.java @@ -0,0 +1,138 @@ +package com.baeldung.breakcontinue; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * @author Santosh + * + */ +public class BreakContinue { + + public static int unlabeledBreak() { + String searchName = "Wilson"; + int counter = 0; + List names = Arrays.asList("John", "Peter", "Robert", "Wilson", "Anthony", "Donald", "Richard"); + + for (String name : names) { + counter++; + if (name.equalsIgnoreCase(searchName)) { + break; + } + } + + return counter; + } + + public static int unlabeledBreakNestedLoops() { + String searchName = "Wilson"; + int counter = 0; + Map> nameMap = new HashMap<>(); + nameMap.put("Grade1", Arrays.asList("John", "Peter", "Robert", "Wilson")); + nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Richard", "Arnold")); + nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Stephen", "Ryan")); + + Iterator>> iterator = nameMap.entrySet() + .iterator(); + Entry> entry = null; + List names = null; + while (iterator.hasNext()) { + entry = iterator.next(); + names = entry.getValue(); + for (String name : names) { + if (name.equalsIgnoreCase(searchName)) { + counter++; + break; + } + } + } + + return counter; + } + + public static int labeledBreak() { + String searchName = "Wilson"; + int counter = 0; + Map> nameMap = new HashMap<>(); + nameMap.put("Grade1", Arrays.asList("John", "Peter", "Robert", "Wilson")); + nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Richard", "Arnold")); + nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Stephen", "Ryan")); + + Iterator>> iterator = nameMap.entrySet() + .iterator(); + Entry> entry = null; + List names = null; + compare: + while (iterator.hasNext()) { + entry = iterator.next(); + names = entry.getValue(); + for (String name : names) { + if (name.equalsIgnoreCase(searchName)) { + counter++; + break compare; + } + } + } + + return counter; + } + + public static int unlabeledContinue() { + String searchName = "Wilson"; + int counter = 0; + Map> nameMap = new HashMap<>(); + nameMap.put("Grade1", Arrays.asList("John", "Wilson", "Robert", "Wilson")); + nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Wilson", "Arnold")); + nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Wilson", "Ryan")); + + Iterator>> iterator = nameMap.entrySet() + .iterator(); + Entry> entry = null; + List names = null; + while (iterator.hasNext()) { + entry = iterator.next(); + names = entry.getValue(); + for (String name : names) { + if (!name.equalsIgnoreCase(searchName)) { + continue; + } + + counter++; + } + } + + return counter; + } + + public static int labeledContinue() { + String searchName = "Wilson"; + int counter = 0; + Map> nameMap = new HashMap<>(); + nameMap.put("Grade1", Arrays.asList("John", "Wilson", "Robert", "Wilson")); + nameMap.put("Grade2", Arrays.asList("Anthony", "Donald", "Wilson", "Arnold")); + nameMap.put("Grade3", Arrays.asList("Wilson", "Michael", "Wilson", "Ryan")); + + Iterator>> iterator = nameMap.entrySet() + .iterator(); + Entry> entry = null; + List names = null; + compare: + while (iterator.hasNext()) { + entry = iterator.next(); + names = entry.getValue(); + for (String name : names) { + if (name.equalsIgnoreCase(searchName)) { + counter++; + continue compare; + } + } + } + + return counter; + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparable/Player.java b/core-java/src/main/java/com/baeldung/comparable/Player.java new file mode 100644 index 0000000000..68a78980f3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparable/Player.java @@ -0,0 +1,51 @@ +package com.baeldung.comparable; + +public class Player implements Comparable { + + private int ranking; + + private String name; + + private int age; + + public Player(int ranking, String name, int age) { + this.ranking = ranking; + this.name = name; + this.age = age; + } + + public int getRanking() { + return ranking; + } + + public void setRanking(int ranking) { + this.ranking = ranking; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return this.name; + } + + @Override + public int compareTo(Player otherPlayer) { + return (this.getRanking() - otherPlayer.getRanking()); + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparable/PlayerSorter.java b/core-java/src/main/java/com/baeldung/comparable/PlayerSorter.java new file mode 100644 index 0000000000..a9b883f579 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparable/PlayerSorter.java @@ -0,0 +1,25 @@ +package com.baeldung.comparable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PlayerSorter { + + public static void main(String[] args) { + + List footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 20); + Player player2 = new Player(67, "Roger", 22); + Player player3 = new Player(45, "Steven", 24); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + + System.out.println("Before Sorting : " + footballTeam); + Collections.sort(footballTeam); + System.out.println("After Sorting : " + footballTeam); + + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparator/Player.java b/core-java/src/main/java/com/baeldung/comparator/Player.java new file mode 100644 index 0000000000..e6e9ee0db6 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparator/Player.java @@ -0,0 +1,46 @@ +package com.baeldung.comparator; + +public class Player { + + private int ranking; + + private String name; + + private int age; + + public Player(int ranking, String name, int age) { + this.ranking = ranking; + this.name = name; + this.age = age; + } + + public int getRanking() { + return ranking; + } + + public void setRanking(int ranking) { + this.ranking = ranking; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return this.name; + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparator/PlayerAgeComparator.java b/core-java/src/main/java/com/baeldung/comparator/PlayerAgeComparator.java new file mode 100644 index 0000000000..d2e7ca1f42 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparator/PlayerAgeComparator.java @@ -0,0 +1,12 @@ +package com.baeldung.comparator; + +import java.util.Comparator; + +public class PlayerAgeComparator implements Comparator { + + @Override + public int compare(Player firstPlayer, Player secondPlayer) { + return (firstPlayer.getAge() - secondPlayer.getAge()); + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparator/PlayerAgeSorter.java b/core-java/src/main/java/com/baeldung/comparator/PlayerAgeSorter.java new file mode 100644 index 0000000000..3bbbcddb80 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparator/PlayerAgeSorter.java @@ -0,0 +1,27 @@ +package com.baeldung.comparator; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PlayerAgeSorter { + + public static void main(String[] args) { + + List footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 22); + Player player2 = new Player(67, "Roger", 20); + Player player3 = new Player(45, "Steven", 24); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + + System.out.println("Before Sorting : " + footballTeam); + //Instance of PlayerAgeComparator + PlayerAgeComparator playerComparator = new PlayerAgeComparator(); + Collections.sort(footballTeam, playerComparator); + System.out.println("After Sorting by age : " + footballTeam); + + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparator/PlayerRankingComparator.java b/core-java/src/main/java/com/baeldung/comparator/PlayerRankingComparator.java new file mode 100644 index 0000000000..2d42698843 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparator/PlayerRankingComparator.java @@ -0,0 +1,12 @@ +package com.baeldung.comparator; + +import java.util.Comparator; + +public class PlayerRankingComparator implements Comparator { + + @Override + public int compare(Player firstPlayer, Player secondPlayer) { + return (firstPlayer.getRanking() - secondPlayer.getRanking()); + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparator/PlayerRankingSorter.java b/core-java/src/main/java/com/baeldung/comparator/PlayerRankingSorter.java new file mode 100644 index 0000000000..581585fb7e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparator/PlayerRankingSorter.java @@ -0,0 +1,27 @@ +package com.baeldung.comparator; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PlayerRankingSorter { + + public static void main(String[] args) { + + List footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 22); + Player player2 = new Player(67, "Roger", 20); + Player player3 = new Player(45, "Steven", 40); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + + System.out.println("Before Sorting : " + footballTeam); + //Instance of PlayerRankingComparator + PlayerRankingComparator playerComparator = new PlayerRankingComparator(); + Collections.sort(footballTeam, playerComparator); + System.out.println("After Sorting by ranking : " + footballTeam); + + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java index 9d4fcf3574..79f618d038 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java @@ -5,16 +5,16 @@ import static com.baeldung.designpatterns.util.LogerUtil.LOG; public class AdapterPatternDriver { public static void main(String args[]) { - LuxuryCars bugattiVeyron = new BugattiVeyron(); - LuxuryCarsAdapter bugattiVeyronAdapter = new LuxuryCarsAdapterImpl(bugattiVeyron); - LOG.info("Bugatti Veyron Super Sport's top speed is " + bugattiVeyronAdapter.speedInKMPH() + " Kmph."); + Movable bugattiVeyron = new BugattiVeyron(); + MovableAdapter bugattiVeyronAdapter = new MovableAdapterImpl(bugattiVeyron); + LOG.info("Bugatti Veyron Super Sport's top speed is " + bugattiVeyronAdapter.getSpeed() + " Kmph."); - LuxuryCars mcLaren = new McLaren(); - LuxuryCarsAdapter mcLarenAdapter = new LuxuryCarsAdapterImpl(mcLaren); - LOG.info("McLaren F1 top speed is " + mcLarenAdapter.speedInKMPH() + " Kmph."); + Movable mcLaren = new McLaren(); + MovableAdapter mcLarenAdapter = new MovableAdapterImpl(mcLaren); + LOG.info("McLaren F1 top speed is " + mcLarenAdapter.getSpeed() + " Kmph."); - LuxuryCars astonMartin = new AstonMartin(); - LuxuryCarsAdapter astonMartinAdapter = new LuxuryCarsAdapterImpl(astonMartin); - LOG.info("McLaren F1 top speed is " + astonMartinAdapter.speedInKMPH() + " Kmph."); + Movable astonMartin = new AstonMartin(); + MovableAdapter astonMartinAdapter = new MovableAdapterImpl(astonMartin); + LOG.info("McLaren F1 top speed is " + astonMartinAdapter.getSpeed() + " Kmph."); } } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/AstonMartin.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/AstonMartin.java index b1fba0dae3..7dd83079a2 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/AstonMartin.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/AstonMartin.java @@ -1,8 +1,8 @@ package com.baeldung.designpatterns.adapter; -public class AstonMartin implements LuxuryCars { +public class AstonMartin implements Movable { @Override - public double speedInMPH() { + public double getSpeed() { return 220; } } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/BugattiVeyron.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/BugattiVeyron.java index 1b0b834448..a249d64b6f 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/BugattiVeyron.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/BugattiVeyron.java @@ -1,8 +1,8 @@ package com.baeldung.designpatterns.adapter; -public class BugattiVeyron implements LuxuryCars { +public class BugattiVeyron implements Movable { @Override - public double speedInMPH() { + public double getSpeed() { return 268; } } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCars.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCars.java deleted file mode 100644 index 9926f5f8bc..0000000000 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCars.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.baeldung.designpatterns.adapter; - -public interface LuxuryCars { - public double speedInMPH(); -} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsAdapter.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsAdapter.java deleted file mode 100644 index f945e1b389..0000000000 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsAdapter.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.baeldung.designpatterns.adapter; - -public interface LuxuryCarsAdapter { - public double speedInKMPH(); -} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/McLaren.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/McLaren.java index e2ba2b830d..c807df67db 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/McLaren.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/McLaren.java @@ -1,8 +1,8 @@ package com.baeldung.designpatterns.adapter; -public class McLaren implements LuxuryCars { +public class McLaren implements Movable { @Override - public double speedInMPH() { + public double getSpeed() { return 241; } } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/Movable.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/Movable.java new file mode 100644 index 0000000000..ec94e90af0 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/Movable.java @@ -0,0 +1,6 @@ +package com.baeldung.designpatterns.adapter; + +public interface Movable { + // returns speed in MPH + double getSpeed(); +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapter.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapter.java new file mode 100644 index 0000000000..b9c7484446 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapter.java @@ -0,0 +1,6 @@ +package com.baeldung.designpatterns.adapter; + +public interface MovableAdapter { + // returns speed in KMPH + double getSpeed(); +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsAdapterImpl.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapterImpl.java similarity index 50% rename from core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsAdapterImpl.java rename to core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapterImpl.java index f2bf553292..eb74641389 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsAdapterImpl.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapterImpl.java @@ -1,15 +1,15 @@ package com.baeldung.designpatterns.adapter; -public class LuxuryCarsAdapterImpl implements LuxuryCarsAdapter { - private LuxuryCars luxuryCars; +public class MovableAdapterImpl implements MovableAdapter { + private Movable luxuryCars; - public LuxuryCarsAdapterImpl(LuxuryCars luxuryCars) { + public MovableAdapterImpl(Movable luxuryCars) { this.luxuryCars = luxuryCars; } @Override - public double speedInKMPH() { - double mph = luxuryCars.speedInMPH(); + public double getSpeed() { + double mph = luxuryCars.getSpeed(); return convertMPHtoKMPH(mph); } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java index ed3f75b4a1..da5d29617f 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java @@ -1,12 +1,8 @@ package com.baeldung.designpatterns.bridge; -import static com.baeldung.designpatterns.util.LogerUtil.LOG; - public class Blue implements Color { - @Override - public void fillColor() { - LOG.info("Color : Blue"); + public String fill() { + return "Color is Blue"; } - } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java index 921deadcac..e6a7fb41c1 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java @@ -5,10 +5,10 @@ public class BridgePatternDriver { public static void main(String[] args) { //a square with red color Shape square = new Square(new Red()); - square.drawShape(); + System.out.println(square.draw()); //a triangle with blue color Shape triangle = new Triangle(new Blue()); - triangle.drawShape(); + System.out.println(triangle.draw()); } } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java index 91d2b01609..05618e6d6e 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java @@ -1,5 +1,5 @@ package com.baeldung.designpatterns.bridge; public interface Color { - public void fillColor(); + String fill(); } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java index 8c22a94f00..bc83199591 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java @@ -1,12 +1,10 @@ package com.baeldung.designpatterns.bridge; -import static com.baeldung.designpatterns.util.LogerUtil.LOG; - public class Red implements Color { @Override - public void fillColor() { - LOG.info("Color : Red"); + public String fill() { + return "Color is Red"; } } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java index c4daf7a821..75cd43dbc8 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java @@ -7,5 +7,5 @@ public abstract class Shape { this.color = color; } - abstract public void drawShape(); + abstract public String draw(); } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java index 6b377197eb..7397f4bd47 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java @@ -1,7 +1,5 @@ package com.baeldung.designpatterns.bridge; -import static com.baeldung.designpatterns.util.LogerUtil.LOG; - public class Square extends Shape { public Square(Color color) { @@ -9,8 +7,7 @@ public class Square extends Shape { } @Override - public void drawShape() { - LOG.info("Square drawn. "); - color.fillColor(); + public String draw() { + return "Square drawn. " + color.fill(); } } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java index 900e78cf2b..46db66ee42 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java @@ -1,7 +1,5 @@ package com.baeldung.designpatterns.bridge; -import static com.baeldung.designpatterns.util.LogerUtil.LOG; - public class Triangle extends Shape { public Triangle(Color color) { @@ -9,8 +7,7 @@ public class Triangle extends Shape { } @Override - public void drawShape() { - LOG.info("Triangle drawn. "); - color.fillColor(); + public String draw() { + return "Triangle drawn. "+ color.fill(); } } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractFactory.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractFactory.java new file mode 100644 index 0000000000..46d97d1a15 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractFactory.java @@ -0,0 +1,6 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public interface AbstractFactory { + Animal getAnimal(String toyType) ; + Color getColor(String colorType); +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternDriver.java new file mode 100644 index 0000000000..7ab166e16a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternDriver.java @@ -0,0 +1,18 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class AbstractPatternDriver { + public static void main(String[] args) { + AbstractFactory abstractFactory; + + //creating a brown toy dog + abstractFactory = FactoryProvider.getFactory("Toy"); + Animal toy = abstractFactory.getAnimal("Dog"); + + abstractFactory = FactoryProvider.getFactory("Color"); + Color color = abstractFactory.getColor("Brown"); + + String result = "A " + toy.getType() + " with " + color.getColor() + " color " + toy.makeSound(); + + System.out.println(result); + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Animal.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Animal.java new file mode 100644 index 0000000000..59c1336053 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Animal.java @@ -0,0 +1,6 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public interface Animal { + String getType(); + String makeSound(); +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AnimalFactory.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AnimalFactory.java new file mode 100644 index 0000000000..49583c3a98 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AnimalFactory.java @@ -0,0 +1,21 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class AnimalFactory implements AbstractFactory { + + @Override + public Animal getAnimal(String animalType) { + if ("Dog".equalsIgnoreCase(animalType)) { + return new Dog(); + } else if ("Duck".equalsIgnoreCase(animalType)) { + return new Duck(); + } + + return null; + } + + @Override + public Color getColor(String color) { + throw new UnsupportedOperationException(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Brown.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Brown.java new file mode 100644 index 0000000000..f251285ebf --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Brown.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class Brown implements Color { + + @Override + public String getColor() { + return "brown"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Color.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Color.java new file mode 100644 index 0000000000..897bb71f38 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Color.java @@ -0,0 +1,5 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public interface Color { + String getColor(); +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/ColorFactory.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/ColorFactory.java new file mode 100644 index 0000000000..8f7559ff27 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/ColorFactory.java @@ -0,0 +1,21 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class ColorFactory implements AbstractFactory { + + @Override + public Color getColor(String colorType) { + if ("Brown".equalsIgnoreCase(colorType)) { + return new Brown(); + } else if ("White".equalsIgnoreCase(colorType)) { + return new White(); + } + + return null; + } + + @Override + public Animal getAnimal(String toyType) { + throw new UnsupportedOperationException(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Dog.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Dog.java new file mode 100644 index 0000000000..002b5665d3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Dog.java @@ -0,0 +1,15 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class Dog implements Animal { + + @Override + public String getType() { + return "Dog"; + } + + @Override + public String makeSound() { + return "Barks"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Duck.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Duck.java new file mode 100644 index 0000000000..5603ad6eee --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Duck.java @@ -0,0 +1,15 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class Duck implements Animal { + + @Override + public String getType() { + return "Duck"; + } + + @Override + public String makeSound() { + return "Squeks"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/FactoryProvider.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/FactoryProvider.java new file mode 100644 index 0000000000..fcbee1e6de --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/FactoryProvider.java @@ -0,0 +1,15 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class FactoryProvider { + public static AbstractFactory getFactory(String choice){ + + if("Toy".equalsIgnoreCase(choice)){ + return new AnimalFactory(); + } + else if("Color".equalsIgnoreCase(choice)){ + return new ColorFactory(); + } + + return null; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/White.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/White.java new file mode 100644 index 0000000000..62ef8048ea --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/White.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class White implements Color { + + @Override + public String getColor() { + return "White"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BankAccount.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BankAccount.java new file mode 100644 index 0000000000..355fa74895 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BankAccount.java @@ -0,0 +1,64 @@ +package com.baeldung.designpatterns.creational.builder; + +public class BankAccount { + private String name; + private String accountNumber; + private String email; + private boolean newsletter; + + //The constructor that takes a builder from which it will create object + //the access to this is only provided to builder + private BankAccount(BankAccountBuilder builder) { + this.name = builder.name; + this.accountNumber = builder.accountNumber; + this.email = builder.email; + this.newsletter = builder.newsletter; + } + + public static class BankAccountBuilder { + private String name; + private String accountNumber; + private String email; + private boolean newsletter; + + //All Mandatory parameters goes with this constructor + public BankAccountBuilder(String name, String accountNumber) { + this.name = name; + this.accountNumber = accountNumber; + } + + //setters for optional parameters which returns this same builder + //to support fluent design + public BankAccountBuilder withEmail(String email) { + this.email = email; + return this; + } + + public BankAccountBuilder wantNewsletter(boolean newsletter) { + this.newsletter = newsletter; + return this; + } + + //the actual build method that prepares and returns a BankAccount object + public BankAccount build() { + return new BankAccount(this); + } + } + + //getters + public String getName() { + return name; + } + + public String getAccountNumber() { + return accountNumber; + } + + public String getEmail() { + return email; + } + + public boolean isNewsletter() { + return newsletter; + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BuilderPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BuilderPatternDriver.java new file mode 100644 index 0000000000..d92a70e664 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BuilderPatternDriver.java @@ -0,0 +1,16 @@ +package com.baeldung.designpatterns.creational.builder; + +public class BuilderPatternDriver { + public static void main(String[] args) { + BankAccount newAccount = new BankAccount + .BankAccountBuilder("Jon", "22738022275") + .withEmail("jon@example.com") + .wantNewsletter(true) + .build(); + + System.out.println("Name: " + newAccount.getName()); + System.out.println("AccountNumber:" + newAccount.getAccountNumber()); + System.out.println("Email: " + newAccount.getEmail()); + System.out.println("Want News letter?: " + newAccount.isNewsletter()); + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/FactoryDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/FactoryDriver.java new file mode 100644 index 0000000000..64ee307bb8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/FactoryDriver.java @@ -0,0 +1,16 @@ +package com.baeldung.designpatterns.creational.factory; + +public class FactoryDriver { + public static void main(String[] args) { + Polygon p; + PolygonFactory factory = new PolygonFactory(); + + //get the shape which has 4 sides + p = factory.getPolygon(4); + System.out.println("The shape with 4 sides is a " + p.getType()); + + //get the shape which has 4 sides + p = factory.getPolygon(8); + System.out.println("The shape with 8 sides is a " + p.getType()); + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Heptagon.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Heptagon.java new file mode 100644 index 0000000000..935fc2f04c --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Heptagon.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.factory; + +public class Heptagon implements Polygon { + + @Override + public String getType() { + return "Heptagon"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Octagon.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Octagon.java new file mode 100644 index 0000000000..fc62302dc8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Octagon.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.factory; + +public class Octagon implements Polygon { + + @Override + public String getType() { + return "Octagon"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Pentagon.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Pentagon.java new file mode 100644 index 0000000000..65d109b10b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Pentagon.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.factory; + +public class Pentagon implements Polygon { + + @Override + public String getType() { + return "Pentagon"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Polygon.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Polygon.java new file mode 100644 index 0000000000..8364e546b0 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Polygon.java @@ -0,0 +1,5 @@ +package com.baeldung.designpatterns.creational.factory; + +public interface Polygon { + String getType(); +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/PolygonFactory.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/PolygonFactory.java new file mode 100644 index 0000000000..9f34fe77b9 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/PolygonFactory.java @@ -0,0 +1,22 @@ +package com.baeldung.designpatterns.creational.factory; + +public class PolygonFactory { + public Polygon getPolygon(int numberOfSides) { + if(numberOfSides == 3) { + return new Triangle(); + } + if(numberOfSides == 4) { + return new Square(); + } + if(numberOfSides == 5) { + return new Pentagon(); + } + if(numberOfSides == 7) { + return new Heptagon(); + } + else if(numberOfSides == 8) { + return new Octagon(); + } + return null; + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Square.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Square.java new file mode 100644 index 0000000000..805c1c9ae3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Square.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.factory; + +public class Square implements Polygon { + + @Override + public String getType() { + return "Square"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Triangle.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Triangle.java new file mode 100644 index 0000000000..8a8832d8a1 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Triangle.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.factory; + +public class Triangle implements Polygon { + + @Override + public String getType() { + return "Triangle"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/Singleton.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/Singleton.java new file mode 100644 index 0000000000..1a5ac82c89 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/Singleton.java @@ -0,0 +1,13 @@ +package com.baeldung.designpatterns.creational.singleton; + +public class Singleton { + private Singleton() {} + + private static class SingletonHolder { + public static final Singleton instance = new Singleton(); + } + + public static Singleton getInstance() { + return SingletonHolder.instance; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/SingletonDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/SingletonDriver.java new file mode 100644 index 0000000000..1955008d3e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/SingletonDriver.java @@ -0,0 +1,8 @@ +package com.baeldung.designpatterns.creational.singleton; + +public class SingletonDriver { + public static void main(String[] args) { + Singleton instance = Singleton.getInstance(); + System.out.println(instance.toString()); + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java index 80a0865567..e5dca41dd8 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java @@ -1,5 +1,5 @@ package com.baeldung.designpatterns.decorator; public interface ChristmasTree { - public String decorate(); -} + String decorate(); +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java index 96a6bfb878..256b31bc84 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java @@ -1,5 +1,5 @@ package com.baeldung.designpatterns.proxy; public interface ExpensiveObject { - public void process(); + void process(); } diff --git a/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java index 2ed9a27c4c..7c1e291646 100644 --- a/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java +++ b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java @@ -13,6 +13,8 @@ import java.util.Set; public class EchoServer { + private static final String POISON_PILL = "POISON_PILL"; + public static void main(String[] args) throws IOException { Selector selector = Selector.open(); ServerSocketChannel serverSocket = ServerSocketChannel.open(); @@ -30,23 +32,36 @@ public class EchoServer { SelectionKey key = iter.next(); if (key.isAcceptable()) { - SocketChannel client = serverSocket.accept(); - client.configureBlocking(false); - client.register(selector, SelectionKey.OP_READ); + register(selector, serverSocket); } if (key.isReadable()) { - SocketChannel client = (SocketChannel) key.channel(); - client.read(buffer); - buffer.flip(); - client.write(buffer); - buffer.clear(); + answerWithEcho(buffer, key); } iter.remove(); } } } + private static void answerWithEcho(ByteBuffer buffer, SelectionKey key) throws IOException { + SocketChannel client = (SocketChannel) key.channel(); + client.read(buffer); + if (new String(buffer.array()).trim().equals(POISON_PILL)) { + client.close(); + System.out.println("Not accepting client messages anymore"); + } + + buffer.flip(); + client.write(buffer); + buffer.clear(); + } + + private static void register(Selector selector, ServerSocketChannel serverSocket) throws IOException { + SocketChannel client = serverSocket.accept(); + client.configureBlocking(false); + client.register(selector, SelectionKey.OP_READ); + } + public static Process start() throws IOException, InterruptedException { String javaHome = System.getProperty("java.home"); String javaBin = javaHome + File.separator + "bin" + File.separator + "java"; diff --git a/core-java/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java b/core-java/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java index ffc58a1c50..35955032dc 100644 --- a/core-java/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java +++ b/core-java/src/main/java/com/baeldung/java/nio2/watcher/DirectoryWatcherExample.java @@ -10,6 +10,7 @@ import java.nio.file.WatchKey; import java.nio.file.WatchService; public class DirectoryWatcherExample { + public static void main(String[] args) throws IOException, InterruptedException { WatchService watchService = FileSystems.getDefault().newWatchService(); Path path = Paths.get(System.getProperty("user.home")); @@ -21,5 +22,8 @@ public class DirectoryWatcherExample { } key.reset(); } + + watchService.close(); } + } diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java b/core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java new file mode 100644 index 0000000000..9cfcff468e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java @@ -0,0 +1,51 @@ +package com.baeldung.jdbcrowset; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.sql.rowset.JdbcRowSet; +import javax.sql.rowset.RowSetFactory; +import javax.sql.rowset.RowSetProvider; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +public class DatabaseConfiguration { + + + public static Connection geth2Connection() throws Exception { + Class.forName("org.h2.Driver"); + System.out.println("Driver Loaded."); + String url = "jdbc:h2:mem:testdb"; + return DriverManager.getConnection(url, "sa", ""); + } + + public static void initDatabase(Statement stmt) throws SQLException{ + int iter = 1; + while(iter<=5){ + String customer = "Customer"+iter; + String sql ="INSERT INTO customers(id, name) VALUES ("+iter+ ",'"+customer+"');"; + System.out.println("here is sql statmeent for execution: " + sql); + stmt.executeUpdate(sql); + iter++; + } + + int iterb = 1; + while(iterb<=5){ + String associate = "Associate"+iter; + String sql = "INSERT INTO associates(id, name) VALUES("+iterb+",'"+associate+"');"; + System.out.println("here is sql statement for associate:"+ sql); + stmt.executeUpdate(sql); + iterb++; + } + + + } + + + +} diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java b/core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java new file mode 100644 index 0000000000..7d5bb759f5 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java @@ -0,0 +1,24 @@ +package com.baeldung.jdbcrowset; + +import javax.sql.RowSetEvent; +import javax.sql.RowSetListener; + +public class ExampleListener implements RowSetListener { + + + public void cursorMoved(RowSetEvent event) { + System.out.println("ExampleListener alerted of cursorMoved event"); + System.out.println(event.toString()); + } + + public void rowChanged(RowSetEvent event) { + System.out.println("ExampleListener alerted of rowChanged event"); + System.out.println(event.toString()); + } + + public void rowSetChanged(RowSetEvent event) { + System.out.println("ExampleListener alerted of rowSetChanged event"); + System.out.println(event.toString()); + } + +} diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java b/core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java new file mode 100644 index 0000000000..14e738f72d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java @@ -0,0 +1,46 @@ +package com.baeldung.jdbcrowset; + +import java.sql.SQLException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.sql.RowSet; +import javax.sql.rowset.Predicate; + +public class FilterExample implements Predicate { + + private Pattern pattern; + + public FilterExample(String regexQuery) { + if (regexQuery != null && !regexQuery.isEmpty()) { + pattern = Pattern.compile(regexQuery); + } + } + + public boolean evaluate(RowSet rs) { + try { + if (!rs.isAfterLast()) { + String name = rs.getString("name"); + System.out.println(String.format( + "Searching for pattern '%s' in %s", pattern.toString(), + name)); + Matcher matcher = pattern.matcher(name); + return matcher.matches(); + } else + return false; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public boolean evaluate(Object value, int column) throws SQLException { + throw new UnsupportedOperationException("This operation is unsupported."); + } + + public boolean evaluate(Object value, String columnName) + throws SQLException { + throw new UnsupportedOperationException("This operation is unsupported."); + } + +} diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java b/core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java new file mode 100644 index 0000000000..72c462ac42 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java @@ -0,0 +1,139 @@ +package com.baeldung.jdbcrowset; + +import java.io.FileOutputStream; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import com.sun.rowset.*; + +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.FilteredRowSet; +import javax.sql.rowset.JdbcRowSet; +import javax.sql.rowset.JoinRowSet; +import javax.sql.rowset.RowSetFactory; +import javax.sql.rowset.RowSetProvider; +import javax.sql.rowset.WebRowSet; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JdbcRowsetApplication { + + public static void main(String[] args) throws Exception { + SpringApplication.run(JdbcRowsetApplication.class, args); + Statement stmt = null; + try { + Connection conn = DatabaseConfiguration.geth2Connection(); + + String drop = "DROP TABLE IF EXISTS customers, associates;"; + String schema = "CREATE TABLE customers (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id)); "; + String schemapartb = "CREATE TABLE associates (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id));"; + + stmt = conn.createStatement(); + stmt.executeUpdate(drop); + stmt.executeUpdate(schema); + stmt.executeUpdate(schemapartb); + // insert data + DatabaseConfiguration.initDatabase(stmt); + // JdbcRowSet Example + String sql = "SELECT * FROM customers"; + JdbcRowSet jdbcRS; + jdbcRS = new JdbcRowSetImpl(conn); + jdbcRS.setType(ResultSet.TYPE_SCROLL_INSENSITIVE); + jdbcRS.setCommand(sql); + jdbcRS.execute(); + jdbcRS.addRowSetListener(new ExampleListener()); + + while (jdbcRS.next()) { + // each call to next, generates a cursorMoved event + System.out.println("id=" + jdbcRS.getString(1)); + System.out.println("name=" + jdbcRS.getString(2)); + } + + // CachedRowSet Example + String username = "sa"; + String password = ""; + String url = "jdbc:h2:mem:testdb"; + CachedRowSet crs = new CachedRowSetImpl(); + crs.setUsername(username); + crs.setPassword(password); + crs.setUrl(url); + crs.setCommand(sql); + crs.execute(); + crs.addRowSetListener(new ExampleListener()); + while (crs.next()) { + if (crs.getInt("id") == 1) { + System.out.println("CRS found customer1 and will remove the record."); + crs.deleteRow(); + break; + } + } + + // WebRowSet example + WebRowSet wrs = new WebRowSetImpl(); + wrs.setUsername(username); + wrs.setPassword(password); + wrs.setUrl(url); + wrs.setCommand(sql); + wrs.execute(); + FileOutputStream ostream = new FileOutputStream("customers.xml"); + wrs.writeXml(ostream); + + // JoinRowSet example + CachedRowSetImpl customers = new CachedRowSetImpl(); + customers.setUsername(username); + customers.setPassword(password); + customers.setUrl(url); + customers.setCommand(sql); + customers.execute(); + + CachedRowSetImpl associates = new CachedRowSetImpl(); + associates.setUsername(username); + associates.setPassword(password); + associates.setUrl(url); + String associatesSQL = "SELECT * FROM associates"; + associates.setCommand(associatesSQL); + associates.execute(); + + JoinRowSet jrs = new JoinRowSetImpl(); + final String ID = "id"; + final String NAME = "name"; + jrs.addRowSet(customers, ID); + jrs.addRowSet(associates, ID); + jrs.last(); + System.out.println("Total rows: " + jrs.getRow()); + jrs.beforeFirst(); + while (jrs.next()) { + + String string1 = jrs.getString(ID); + String string2 = jrs.getString(NAME); + System.out.println("ID: " + string1 + ", NAME: " + string2); + } + + // FilteredRowSet example + RowSetFactory rsf = RowSetProvider.newFactory(); + FilteredRowSet frs = rsf.createFilteredRowSet(); + frs.setCommand("select * from customers"); + frs.execute(conn); + frs.setFilter(new FilterExample("^[A-C].*")); + + ResultSetMetaData rsmd = frs.getMetaData(); + int columncount = rsmd.getColumnCount(); + while (frs.next()) { + for (int i = 1; i <= columncount; i++) { + System.out.println(rsmd.getColumnLabel(i) + " = " + frs.getObject(i) + " "); + } + } + + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/loops/LoopsInJava.java b/core-java/src/main/java/com/baeldung/loops/LoopsInJava.java new file mode 100644 index 0000000000..1b2e621b52 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/loops/LoopsInJava.java @@ -0,0 +1,43 @@ +package com.baeldung.loops; + +public class LoopsInJava { + + public int[] simple_for_loop() { + int[] arr = new int[5]; + for (int i = 0; i < 5; i++) { + arr[i] = i; + System.out.println("Simple for loop: i - " + i); + } + return arr; + } + + public int[] enhanced_for_each_loop() { + int[] intArr = { 0, 1, 2, 3, 4 }; + int[] arr = new int[5]; + for (int num : intArr) { + arr[num] = num; + System.out.println("Enhanced for-each loop: i - " + num); + } + return arr; + } + + public int[] while_loop() { + int i = 0; + int[] arr = new int[5]; + while (i < 5) { + arr[i] = i; + System.out.println("While loop: i - " + i++); + } + return arr; + } + + public int[] do_while_loop() { + int i = 0; + int[] arr = new int[5]; + do { + arr[i] = i; + System.out.println("Do-While loop: i - " + i++); + } while (i < 5); + return arr; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/polymorphism/FileManager.java b/core-java/src/main/java/com/baeldung/polymorphism/FileManager.java new file mode 100644 index 0000000000..7f2665ff2d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/polymorphism/FileManager.java @@ -0,0 +1,38 @@ +package com.baeldung.polymorphism; + +import java.awt.image.BufferedImage; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileManager { + + final static Logger logger = LoggerFactory.getLogger(FileManager.class); + + public static void main(String[] args) { + GenericFile file1 = new TextFile("SampleTextFile", "This is a sample text content", "v1.0.0"); + logger.info("File Info: \n" + file1.getFileInfo() + "\n"); + ImageFile imageFile = new ImageFile("SampleImageFile", 200, 100, new BufferedImage(100, 200, BufferedImage.TYPE_INT_RGB).toString() + .getBytes(), "v1.0.0"); + logger.info("File Info: \n" + imageFile.getFileInfo()); + } + + public static ImageFile createImageFile(String name, int height, int width, byte[] content, String version) { + ImageFile imageFile = new ImageFile(name, height, width, content, version); + logger.info("File 2 Info: \n" + imageFile.getFileInfo()); + return imageFile; + } + + public static GenericFile createTextFile(String name, String content, String version) { + GenericFile file1 = new TextFile(name, content, version); + logger.info("File 1 Info: \n" + file1.getFileInfo() + "\n"); + return file1; + } + + public static TextFile createTextFile2(String name, String content, String version) { + TextFile file1 = new TextFile(name, content, version); + logger.info("File 1 Info: \n" + file1.getFileInfo() + "\n"); + return file1; + } + +} diff --git a/core-java/src/main/java/com/baeldung/polymorphism/GenericFile.java b/core-java/src/main/java/com/baeldung/polymorphism/GenericFile.java new file mode 100644 index 0000000000..4075083c49 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/polymorphism/GenericFile.java @@ -0,0 +1,63 @@ +package com.baeldung.polymorphism; + +import java.util.Date; + +public class GenericFile { + private String name; + private String extension; + private Date dateCreated; + private String version; + private byte[] content; + + public GenericFile() { + this.setDateCreated(new Date()); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getExtension() { + return extension; + } + + public void setExtension(String extension) { + this.extension = extension; + } + + public Date getDateCreated() { + return dateCreated; + } + + public void setDateCreated(Date dateCreated) { + this.dateCreated = dateCreated; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public byte[] getContent() { + return content; + } + + public void setContent(byte[] content) { + this.content = content; + } + + public String getFileInfo() { + return "File Name: " + this.getName() + "\n" + "Extension: " + this.getExtension() + "\n" + "Date Created: " + this.getDateCreated() + "\n" + "Version: " + this.getVersion() + "\n"; + } + + public Object read() { + return content; + } +} diff --git a/core-java/src/main/java/com/baeldung/polymorphism/ImageFile.java b/core-java/src/main/java/com/baeldung/polymorphism/ImageFile.java new file mode 100644 index 0000000000..ac72a40993 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/polymorphism/ImageFile.java @@ -0,0 +1,41 @@ +package com.baeldung.polymorphism; + +public class ImageFile extends GenericFile { + private int height; + private int width; + + public ImageFile(String name, int height, int width, byte[] content, String version) { + this.setHeight(height); + this.setWidth(width); + this.setContent(content); + this.setName(name); + this.setVersion(version); + this.setExtension(".jpg"); + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public String getFileInfo() { + return super.getFileInfo() + "Height: " + this.getHeight() + "\n" + "Width: " + this.getWidth(); + } + + public String read() { + return this.getContent() + .toString(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/polymorphism/TextFile.java b/core-java/src/main/java/com/baeldung/polymorphism/TextFile.java new file mode 100644 index 0000000000..8280b4ee95 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/polymorphism/TextFile.java @@ -0,0 +1,44 @@ +package com.baeldung.polymorphism; + +public class TextFile extends GenericFile { + private int wordCount; + + public TextFile(String name, String content, String version) { + String[] words = content.split(" "); + this.setWordCount(words.length > 0 ? words.length : 1); + this.setContent(content.getBytes()); + this.setName(name); + this.setVersion(version); + this.setExtension(".txt"); + } + + public int getWordCount() { + return wordCount; + } + + public void setWordCount(int wordCount) { + this.wordCount = wordCount; + } + + public String getFileInfo() { + return super.getFileInfo() + "Word Count: " + wordCount; + } + + public String read() { + return this.getContent() + .toString(); + } + + public String read(int limit) { + return this.getContent() + .toString() + .substring(0, limit); + } + + public String read(int start, int stop) { + return this.getContent() + .toString() + .substring(start, stop); + } + +} diff --git a/core-java/src/main/java/com/baeldung/staticdemo/Car.java b/core-java/src/main/java/com/baeldung/staticdemo/Car.java new file mode 100644 index 0000000000..cdb3806c35 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/staticdemo/Car.java @@ -0,0 +1,48 @@ +package com.baeldung.staticdemo; + +/** + * This class demonstrates the use of static fields and static methods + * the instance variables engine and displacement are distinct for + * each and every object whereas static/class variable numberOfCars + * is unique and is shared across all objects of this class. + * + * @author baeldung + * + */ +public class Car { + private String name; + private String engine; + + public static int numberOfCars; + + public Car(String name, String engine) { + this.name = name; + this.engine = engine; + numberOfCars++; + } + + //getters and setters + public static int getNumberOfCars() { + return numberOfCars; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEngine() { + return engine; + } + + public void setEngine(String engine) { + this.engine = engine; + } + + public static void setNumberOfCars(int numberOfCars) { + Car.numberOfCars = numberOfCars; + } +} diff --git a/core-java/src/main/java/com/baeldung/staticdemo/Singleton.java b/core-java/src/main/java/com/baeldung/staticdemo/Singleton.java new file mode 100644 index 0000000000..de75af9d9d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/staticdemo/Singleton.java @@ -0,0 +1,13 @@ +package com.baeldung.staticdemo; + +public class Singleton { + private Singleton() {} + + private static class SingletonHolder { + public static final Singleton instance = new Singleton(); + } + + public static Singleton getInstance() { + return SingletonHolder.instance; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/staticdemo/StaticBlock.java b/core-java/src/main/java/com/baeldung/staticdemo/StaticBlock.java new file mode 100644 index 0000000000..fde7afb090 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/staticdemo/StaticBlock.java @@ -0,0 +1,28 @@ +package com.baeldung.staticdemo; + +import java.util.LinkedList; +import java.util.List; + +public class StaticBlock { + private static List ranks = new LinkedList<>(); + + static { + ranks.add("Lieutenant"); + ranks.add("Captain"); + ranks.add("Major"); + } + + static { + ranks.add("Colonel"); + ranks.add("General"); + } + + //getters and setters + public static List getRanks() { + return ranks; + } + + public static void setRanks(List ranks) { + StaticBlock.ranks = ranks; + } +} diff --git a/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java b/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java new file mode 100644 index 0000000000..4882ebe175 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java @@ -0,0 +1,43 @@ +package com.baeldung.timezonedisplay; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; + +public class TimezoneDisplayJava7 { + + public enum OffsetBase { + GMT, UTC + } + + public List getTimeZoneList(TimezoneDisplayJava7.OffsetBase base) { + String[] availableZoneIds = TimeZone.getAvailableIDs(); + List result = new ArrayList<>(availableZoneIds.length); + + for (String zoneId : availableZoneIds) { + TimeZone curTimeZone = TimeZone.getTimeZone(zoneId); + + String offset = calculateOffset(curTimeZone.getRawOffset()); + + result.add(String.format("(%s%s) %s", base, offset, zoneId)); + } + + Collections.sort(result); + + return result; + } + + private String calculateOffset(int rawOffset) { + if (rawOffset == 0) { + return "+00:00"; + } + long hours = TimeUnit.MILLISECONDS.toHours(rawOffset); + long minutes = TimeUnit.MILLISECONDS.toMinutes(rawOffset); + minutes = Math.abs(minutes - TimeUnit.HOURS.toMinutes(hours)); + + return String.format("%+03d:%02d", hours, Math.abs(minutes)); + } + +} diff --git a/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java b/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java new file mode 100644 index 0000000000..9f20667660 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java @@ -0,0 +1,23 @@ +package com.baeldung.timezonedisplay; + +import java.util.List; + +public class TimezoneDisplayJava7App { + + public static void main(String... args) { + TimezoneDisplayJava7 display = new TimezoneDisplayJava7(); + + System.out.println("Time zones in UTC:"); + List utc = display.getTimeZoneList(TimezoneDisplayJava7.OffsetBase.UTC); + for (String timeZone : utc) { + System.out.println(timeZone); + } + + System.out.println("Time zones in GMT:"); + List gmt = display.getTimeZoneList(TimezoneDisplayJava7.OffsetBase.GMT); + for (String timeZone : gmt) { + System.out.println(timeZone); + } + } + +} diff --git a/core-java/src/main/java/com/baeldung/util/StreamUtils.java b/core-java/src/main/java/com/baeldung/util/StreamUtils.java new file mode 100644 index 0000000000..42f438732f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/util/StreamUtils.java @@ -0,0 +1,16 @@ +package com.baeldung.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; + +import org.apache.commons.io.IOUtils; + +public class StreamUtils { + + public static String getStringFromInputStream(InputStream input) throws IOException { + StringWriter writer = new StringWriter(); + IOUtils.copy(input, writer, "UTF-8"); + return writer.toString(); + } +} diff --git a/core-java/src/main/resources/META-INF/services/com.sun.source.util.Plugin b/core-java/src/main/resources/META-INF/services/com.sun.source.util.Plugin new file mode 100644 index 0000000000..91fb6eb3b0 --- /dev/null +++ b/core-java/src/main/resources/META-INF/services/com.sun.source.util.Plugin @@ -0,0 +1 @@ +com.baeldung.javac.SampleJavacPlugin \ No newline at end of file diff --git a/core-java/src/main/resources/countries.properties b/core-java/src/main/resources/countries.properties new file mode 100644 index 0000000000..e743b5a40b --- /dev/null +++ b/core-java/src/main/resources/countries.properties @@ -0,0 +1,3 @@ +UK +US +Germany diff --git a/core-java/src/test/java/com/baeldung/array/ArrayInitializerTest.java b/core-java/src/test/java/com/baeldung/array/ArrayInitializerTest.java new file mode 100644 index 0000000000..7265fa20e5 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/array/ArrayInitializerTest.java @@ -0,0 +1,74 @@ +package com.baeldung.array; + +import static com.baeldung.array.ArrayInitializer.initializeArrayAtTimeOfDeclarationMethod1; +import static com.baeldung.array.ArrayInitializer.initializeArrayAtTimeOfDeclarationMethod2; +import static com.baeldung.array.ArrayInitializer.initializeArrayAtTimeOfDeclarationMethod3; +import static com.baeldung.array.ArrayInitializer.initializeArrayInLoop; +import static com.baeldung.array.ArrayInitializer.initializeArrayRangeUsingArraysFill; +import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysCopy; +import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysFill; +import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysSetAll; +import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysUtilClone; +import static com.baeldung.array.ArrayInitializer.initializeLargerArrayUsingArraysCopy; +import static com.baeldung.array.ArrayInitializer.initializeMultiDimensionalArrayInLoop; +import static org.junit.Assert.assertArrayEquals; + +import org.junit.Test; + +public class ArrayInitializerTest { + + @Test + public void whenInitializeArrayInLoop_thenCorrect() { + assertArrayEquals(new int[] { 2, 3, 4, 5, 6 }, initializeArrayInLoop()); + } + + @Test + public void whenInitializeMultiDimensionalArrayInLoop_thenCorrect() { + assertArrayEquals(new int[][] { { 1, 2, 3, 4, 5 }, { 1, 2, 3, 4, 5 } }, initializeMultiDimensionalArrayInLoop()); + } + + @Test + public void whenInitializeArrayAtTimeOfDeclarationMethod1_thenCorrect() { + assertArrayEquals(new String[] { "Toyota", "Mercedes", "BMW", "Volkswagen", "Skoda" }, initializeArrayAtTimeOfDeclarationMethod1()); + } + + @Test + public void whenInitializeArrayAtTimeOfDeclarationMethod2_thenCorrect() { + assertArrayEquals(new int[] { 1, 2, 3, 4, 5 }, initializeArrayAtTimeOfDeclarationMethod2()); + } + + @Test + public void whenInitializeArrayAtTimeOfDeclarationMethod3_thenCorrect() { + assertArrayEquals(new int[] { 1, 2, 3, 4, 5 }, initializeArrayAtTimeOfDeclarationMethod3()); + } + + @Test + public void whenInitializeArrayUsingArraysFill_thenCorrect() { + assertArrayEquals(new long[] { 30, 30, 30, 30, 30 }, initializeArrayUsingArraysFill()); + } + + @Test + public void whenInitializeArrayRangeUsingArraysFill_thenCorrect() { + assertArrayEquals(new int[] { -50, -50, -50, 0, 0 }, initializeArrayRangeUsingArraysFill()); + } + + @Test + public void whenInitializeArrayRangeUsingArraysCopy_thenCorrect() { + assertArrayEquals(new int[] { 1, 2, 3, 4, 5 }, initializeArrayUsingArraysCopy()); + } + + @Test + public void whenInitializeLargerArrayRangeUsingArraysCopy_thenCorrect() { + assertArrayEquals(new int[] { 1, 2, 3, 4, 5, 0 }, initializeLargerArrayUsingArraysCopy()); + } + + @Test + public void whenInitializeLargerArrayRangeUsingArraysSetAll_thenCorrect() { + assertArrayEquals(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, initializeArrayUsingArraysSetAll()); + } + + @Test + public void whenInitializeArrayUsingArraysUtilClone_thenCorrect() { + assertArrayEquals(new char[] { 'a', 'b', 'c' }, initializeArrayUsingArraysUtilClone()); + } +} diff --git a/core-java/src/test/java/com/baeldung/array/SearchArrayTest.java b/core-java/src/test/java/com/baeldung/array/SearchArrayTest.java new file mode 100644 index 0000000000..94911baac9 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/array/SearchArrayTest.java @@ -0,0 +1,116 @@ +package com.baeldung.array; + +import org.junit.Test; + +import java.util.*; + +public class SearchArrayTest { + + + @Test + public void searchArrayAllocNewCollections() { + + int count = 1000; + + String[] strings = seedArray(count); + + long startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + searchList(strings, "W"); + } + long duration = System.nanoTime() - startTime; + System.out.println("SearchList: " + duration / 10000); + + startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + searchSet(strings,"S"); + } + duration = System.nanoTime() - startTime; + System.out.println("SearchSet: " + duration / 10000); + + startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + searchLoop(strings, "T"); + } + duration = System.nanoTime() - startTime; + System.out.println("SearchLoop: " + duration / 10000); + } + + @Test + public void searchArrayReuseCollections() { + + int count = 10000; + String[] strings = seedArray(count); + + List asList = Arrays.asList(strings); + Set asSet = new HashSet<>(Arrays.asList(strings)); + + long startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + asList.contains("W"); + } + long duration = System.nanoTime() - startTime; + System.out.println("List: " + duration / 10000); + + startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + asSet.contains("S"); + } + duration = System.nanoTime() - startTime; + System.out.println("Set: " + duration / 10000); + + startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + searchLoop(strings, "T"); + } + duration = System.nanoTime() - startTime; + System.out.println("Loop: " + duration / 10000); + + } + + + @Test + public void searchArrayBinarySearch() { + + int count = 10000; + String[] strings = seedArray(count); + Arrays.sort(strings); + + long startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + Arrays.binarySearch(strings, "A"); + } + long duration = System.nanoTime() - startTime; + System.out.println("Binary search: " + duration / 10000); + + } + + private boolean searchList(String[] strings, String searchString) { + return Arrays.asList(strings).contains(searchString); + } + + private boolean searchSet(String[] strings, String searchString) { + Set set = new HashSet<>(Arrays.asList(strings)); + return set.contains(searchString); + } + + private boolean searchLoop(String[] strings, String searchString) { + for (String s : strings) { + if (s.equals(searchString)) + return true; + } + return false; + } + + private String[] seedArray(int length) { + + String[] strings = new String[length]; + Random random = new Random(); + for (int i = 0; i < length; i++) + { + strings[i] = String.valueOf(random.nextInt()); + } + return strings; + } + +} diff --git a/core-java/src/test/java/com/baeldung/arraydeque/ArrayDequeTest.java b/core-java/src/test/java/com/baeldung/arraydeque/ArrayDequeTest.java new file mode 100644 index 0000000000..50813a8601 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/arraydeque/ArrayDequeTest.java @@ -0,0 +1,50 @@ +package com.baeldung.arraydeque; + +import java.util.ArrayDeque; +import java.util.Deque; + +import static org.junit.Assert.*; +import org.junit.Test; + +public class ArrayDequeTest { + + @Test + public void whenOffer_addsAtLast() { + final Deque deque = new ArrayDeque<>(); + + deque.offer("first"); + deque.offer("second"); + + assertEquals("second", deque.getLast()); + } + + @Test + public void whenPoll_removesFirst() { + final Deque deque = new ArrayDeque<>(); + + deque.offer("first"); + deque.offer("second"); + + assertEquals("first", deque.poll()); + } + + @Test + public void whenPush_addsAtFirst() { + final Deque deque = new ArrayDeque<>(); + + deque.push("first"); + deque.push("second"); + + assertEquals("second", deque.getFirst()); + } + + @Test + public void whenPop_removesLast() { + final Deque deque = new ArrayDeque<>(); + + deque.push("first"); + deque.push("second"); + + assertEquals("second", deque.pop()); + } +} diff --git a/core-java/src/test/java/com/baeldung/breakcontinue/BreakContinueTest.java b/core-java/src/test/java/com/baeldung/breakcontinue/BreakContinueTest.java new file mode 100644 index 0000000000..1980497cd3 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/breakcontinue/BreakContinueTest.java @@ -0,0 +1,39 @@ +package com.baeldung.breakcontinue; + +import static com.baeldung.breakcontinue.BreakContinue.labeledBreak; +import static com.baeldung.breakcontinue.BreakContinue.labeledContinue; +import static com.baeldung.breakcontinue.BreakContinue.unlabeledBreak; +import static com.baeldung.breakcontinue.BreakContinue.unlabeledBreakNestedLoops; +import static com.baeldung.breakcontinue.BreakContinue.unlabeledContinue; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class BreakContinueTest { + + @Test + public void whenUnlabeledBreak_ThenEqual() { + assertEquals(4, unlabeledBreak()); + } + + @Test + public void whenUnlabeledBreakNestedLoops_ThenEqual() { + assertEquals(2, unlabeledBreakNestedLoops()); + } + + @Test + public void whenLabeledBreak_ThenEqual() { + assertEquals(1, labeledBreak()); + } + + @Test + public void whenUnlabeledContinue_ThenEqual() { + assertEquals(5, unlabeledContinue()); + } + + @Test + public void whenLabeledContinue_ThenEqual() { + assertEquals(3, labeledContinue()); + } + +} diff --git a/core-java/src/test/java/com/baeldung/collection/WhenUsingHashSet.java b/core-java/src/test/java/com/baeldung/collection/WhenUsingHashSet.java new file mode 100644 index 0000000000..7dc47ee8c2 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/collection/WhenUsingHashSet.java @@ -0,0 +1,93 @@ +package com.baeldung.collection; + +import java.util.ConcurrentModificationException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; + +public class WhenUsingHashSet { + + @Test + public void whenAddingElement_shouldAddElement() { + Set hashset = new HashSet<>(); + Assert.assertTrue(hashset.add("String Added")); + } + + @Test + public void whenCheckingForElement_shouldSearchForElement() { + Set hashsetContains = new HashSet<>(); + hashsetContains.add("String Added"); + Assert.assertTrue(hashsetContains.contains("String Added")); + } + + @Test + public void whenCheckingTheSizeOfHashSet_shouldReturnThesize() { + Set hashSetSize = new HashSet<>(); + hashSetSize.add("String Added"); + Assert.assertEquals(1, hashSetSize.size()); + } + + @Test + public void whenCheckingForEmptyHashSet_shouldCheckForEmpty() { + Set emptyHashSet = new HashSet<>(); + Assert.assertTrue(emptyHashSet.isEmpty()); + } + + @Test + public void whenRemovingElement_shouldRemoveElement() { + Set removeFromHashSet = new HashSet<>(); + removeFromHashSet.add("String Added"); + Assert.assertTrue(removeFromHashSet.remove("String Added")); + } + + @Test + public void whenClearingHashSet_shouldClearHashSet() { + Set clearHashSet = new HashSet<>(); + clearHashSet.add("String Added"); + clearHashSet.clear(); + Assert.assertTrue(clearHashSet.isEmpty()); + } + + @Test + public void whenIteratingHashSet_shouldIterateHashSet() { + Set hashset = new HashSet<>(); + hashset.add("First"); + hashset.add("Second"); + hashset.add("Third"); + Iterator itr = hashset.iterator(); + while (itr.hasNext()) { + System.out.println(itr.next()); + } + } + + @Test(expected = ConcurrentModificationException.class) + public void whenModifyingHashSetWhileIterating_shouldThrowException() { + Set hashset = new HashSet<>(); + hashset.add("First"); + hashset.add("Second"); + hashset.add("Third"); + Iterator itr = hashset.iterator(); + while (itr.hasNext()) { + itr.next(); + hashset.remove("Second"); + } + } + + @Test + public void whenRemovingElementUsingIterator_shouldRemoveElement() { + Set hashset = new HashSet<>(); + hashset.add("First"); + hashset.add("Second"); + hashset.add("Third"); + Iterator itr = hashset.iterator(); + while (itr.hasNext()) { + String element = itr.next(); + if (element.equals("Second")) + itr.remove(); + } + Assert.assertEquals(2, hashset.size()); + } +} diff --git a/core-java/src/test/java/com/baeldung/comparable/ComparableUnitTest.java b/core-java/src/test/java/com/baeldung/comparable/ComparableUnitTest.java new file mode 100644 index 0000000000..e8745884b8 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/comparable/ComparableUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.comparable; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class ComparableUnitTest { + + @Test + public void whenUsingComparable_thenSortedList() { + List footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 20); + Player player2 = new Player(67, "Roger", 22); + Player player3 = new Player(45, "Steven", 24); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + Collections.sort(footballTeam); + assertEquals(footballTeam.get(0) + .getName(), "Steven"); + assertEquals(footballTeam.get(2) + .getRanking(), 67); + } + +} diff --git a/core-java/src/test/java/com/baeldung/comparator/ComparatorUnitTest.java b/core-java/src/test/java/com/baeldung/comparator/ComparatorUnitTest.java new file mode 100644 index 0000000000..5b7ec3bfe4 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/comparator/ComparatorUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.comparator; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +public class ComparatorUnitTest { + + List footballTeam; + + @Before + public void setUp() { + footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 20); + Player player2 = new Player(67, "Roger", 22); + Player player3 = new Player(45, "Steven", 24); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + } + + @Test + public void whenUsingRankingComparator_thenSortedList() { + PlayerRankingComparator playerComparator = new PlayerRankingComparator(); + Collections.sort(footballTeam, playerComparator); + assertEquals(footballTeam.get(0) + .getName(), "Steven"); + assertEquals(footballTeam.get(2) + .getRanking(), 67); + } + + @Test + public void whenUsingAgeComparator_thenSortedList() { + PlayerAgeComparator playerComparator = new PlayerAgeComparator(); + Collections.sort(footballTeam, playerComparator); + assertEquals(footballTeam.get(0) + .getName(), "John"); + assertEquals(footballTeam.get(2) + .getRanking(), 45); + } + +} diff --git a/core-java/src/test/java/com/baeldung/comparator/Java8ComparatorUnitTest.java b/core-java/src/test/java/com/baeldung/comparator/Java8ComparatorUnitTest.java new file mode 100644 index 0000000000..49c8749309 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/comparator/Java8ComparatorUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.comparator; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +public class Java8ComparatorUnitTest { + + List footballTeam; + + @Before + public void setUp() { + footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 22); + Player player2 = new Player(67, "Roger", 20); + Player player3 = new Player(45, "Steven", 24); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + } + + @Test + public void whenComparing_UsingLambda_thenSorted() { + System.out.println("************** Java 8 Comaparator **************"); + Comparator byRanking = (Player player1, Player player2) -> player1.getRanking() - player2.getRanking(); + + System.out.println("Before Sorting : " + footballTeam); + Collections.sort(footballTeam, byRanking); + System.out.println("After Sorting : " + footballTeam); + assertEquals(footballTeam.get(0) + .getName(), "Steven"); + assertEquals(footballTeam.get(2) + .getRanking(), 67); + } + + @Test + public void whenComparing_UsingComparatorComparing_thenSorted() { + System.out.println("********* Comaparator.comparing method *********"); + System.out.println("********* byRanking *********"); + Comparator byRanking = Comparator.comparing(Player::getRanking); + + System.out.println("Before Sorting : " + footballTeam); + Collections.sort(footballTeam, byRanking); + System.out.println("After Sorting : " + footballTeam); + assertEquals(footballTeam.get(0) + .getName(), "Steven"); + assertEquals(footballTeam.get(2) + .getRanking(), 67); + + System.out.println("********* byAge *********"); + Comparator byAge = Comparator.comparing(Player::getAge); + + System.out.println("Before Sorting : " + footballTeam); + Collections.sort(footballTeam, byAge); + System.out.println("After Sorting : " + footballTeam); + assertEquals(footballTeam.get(0) + .getName(), "Roger"); + assertEquals(footballTeam.get(2) + .getRanking(), 45); + } + +} diff --git a/core-java/src/test/java/com/baeldung/copyfiles/FileCopierTest.java b/core-java/src/test/java/com/baeldung/copyfiles/FileCopierTest.java new file mode 100644 index 0000000000..973436a26a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/copyfiles/FileCopierTest.java @@ -0,0 +1,70 @@ +package com.baeldung.copyfiles; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Test; +import static org.assertj.core.api.Assertions.*; + +public class FileCopierTest { + File original = new File("src/test/resources/original.txt"); + + @Before + public void init() throws IOException { + if (!original.exists()) + Files.createFile(original.toPath()); + } + + @Test + public void givenIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { + File copied = new File("src/test/resources/copiedWithIo.txt"); + try (InputStream in = new BufferedInputStream(new FileInputStream(original)); + OutputStream out = new BufferedOutputStream(new FileOutputStream(copied))) { + byte[] buffer = new byte[1024]; + int lengthRead; + while ((lengthRead = in.read(buffer)) > 0) { + out.write(buffer, 0, lengthRead); + out.flush(); + } + } + assertThat(copied).exists(); + assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); + } + + @Test + public void givenCommonsIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { + File copied = new File("src/test/resources/copiedWithApacheCommons.txt"); + FileUtils.copyFile(original, copied); + assertThat(copied).exists(); + assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); + } + + @Test + public void givenNIO2_whenCopied_thenCopyExistsWithSameContents() throws IOException { + Path copied = Paths.get("src/test/resources/copiedWithNio.txt"); + Path originalPath = original.toPath(); + Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING); + assertThat(copied).exists(); + assertThat(Files.readAllLines(originalPath).equals(Files.readAllLines(copied))); + } + + @Test + public void givenGuava_whenCopied_thenCopyExistsWithSameContents() throws IOException { + File copied = new File("src/test/resources/copiedWithApacheCommons.txt"); + com.google.common.io.Files.copy(original, copied); + assertThat(copied).exists(); + assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); + } +} diff --git a/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java index e56e271743..8cad1290d9 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java +++ b/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java @@ -6,15 +6,25 @@ import org.junit.Test; import com.baeldung.designpatterns.adapter.AstonMartin; import com.baeldung.designpatterns.adapter.BugattiVeyron; -import com.baeldung.designpatterns.adapter.LuxuryCarsAdapterImpl; import com.baeldung.designpatterns.adapter.McLaren; +import com.baeldung.designpatterns.adapter.Movable; +import com.baeldung.designpatterns.adapter.MovableAdapter; +import com.baeldung.designpatterns.adapter.MovableAdapterImpl; public class AdapterPatternIntegrationTest { @Test - public void givenLuxuryCarsAdapter_WhenConvertingMPHToKMPH_thenSuccessfullyConverted() { - assertEquals(new LuxuryCarsAdapterImpl(new BugattiVeyron()).speedInKMPH(), 431.30312, 0.00001); - assertEquals(new LuxuryCarsAdapterImpl(new McLaren()).speedInKMPH(), 387.85094, 0.00001); - assertEquals(new LuxuryCarsAdapterImpl(new AstonMartin()).speedInKMPH(), 354.0548, 0.00001); + public void givenMovableAdapter_WhenConvertingMPHToKMPH_thenSuccessfullyConverted() { + Movable bugattiVeyron = new BugattiVeyron(); + MovableAdapter bugattiVeyronAdapter = new MovableAdapterImpl(bugattiVeyron); + assertEquals(bugattiVeyronAdapter.getSpeed(), 431.30312, 0.00001); + + Movable mcLaren = new McLaren(); + MovableAdapter mcLarenAdapter = new MovableAdapterImpl(mcLaren); + assertEquals(mcLarenAdapter.getSpeed(), 387.85094, 0.00001); + + Movable astonMartin = new AstonMartin(); + MovableAdapter astonMartinAdapter = new MovableAdapterImpl(astonMartin); + assertEquals(astonMartinAdapter.getSpeed(), 354.0548, 0.00001); } } diff --git a/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java index 56a7a704f2..ed7eb0c453 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java +++ b/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java @@ -1,14 +1,7 @@ package com.baeldung.designpatterns; -import static com.baeldung.designpatterns.util.LogerUtil.LOG; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.*; -import java.util.List; - -import org.apache.log4j.spi.LoggingEvent; -import org.junit.After; -import org.junit.Before; import org.junit.Test; import com.baeldung.designpatterns.bridge.Blue; @@ -18,35 +11,16 @@ import com.baeldung.designpatterns.bridge.Square; import com.baeldung.designpatterns.bridge.Triangle; public class BridgePatternIntegrationTest { - public static TestAppenderDP appender; - - @Before - public void setUp() { - appender = new TestAppenderDP(); - LOG.addAppender(appender); - } - + @Test public void whenBridgePatternInvoked_thenConfigSuccess() { //a square with red color Shape square = new Square(new Red()); - square.drawShape(); + assertEquals(square.draw(), "Square drawn. Color is Red"); //a triangle with blue color Shape triangle = new Triangle(new Blue()); - triangle.drawShape(); - - final List log = appender.getLog(); - - assertThat((String) log.get(0).getMessage(), is("Square drawn. ")); - assertThat((String) log.get(1).getMessage(), is("Color : Red")); - assertThat((String) log.get(2).getMessage(), is("Triangle drawn. ")); - assertThat((String) log.get(3).getMessage(), is("Color : Blue")); - } - - @After - public void tearDown() { - LOG.removeAppender(appender); + assertEquals(triangle.draw(), "Triangle drawn. Color is Blue"); } } diff --git a/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java index b3b3f988f1..de0ca8a135 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java +++ b/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java @@ -10,19 +10,16 @@ import com.baeldung.designpatterns.decorator.ChristmasTreeImpl; import com.baeldung.designpatterns.decorator.Garland; public class DecoratorPatternIntegrationTest { - private ChristmasTree tree; - @Test public void givenDecoratorPattern_WhenDecoratorsInjectedAtRuntime_thenConfigSuccess() { - //christmas tree with just one Garland - tree = new Garland(new ChristmasTreeImpl()); - assertEquals(tree.decorate(), "Christmas tree with Garland"); - - //christmas tree with two Garlands and one Bubble lights - tree = new BubbleLights(new Garland( - new Garland(new ChristmasTreeImpl())) - ); - assertEquals(tree.decorate(), "Christmas tree with Garland with Garland with Bubble Lights"); + ChristmasTree tree1 = new Garland(new ChristmasTreeImpl()); + assertEquals(tree1.decorate(), + "Christmas tree with Garland"); + + ChristmasTree tree2 = new BubbleLights( + new Garland(new Garland(new ChristmasTreeImpl()))); + assertEquals(tree2.decorate(), + "Christmas tree with Garland with Garland with Bubble Lights"); } } diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternIntegrationTest.java new file mode 100644 index 0000000000..dc02b976a0 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternIntegrationTest.java @@ -0,0 +1,23 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class AbstractPatternIntegrationTest { + @Test + public void givenAbstractFactory_whenGettingObjects_thenSuccessful() { + AbstractFactory abstractFactory; + + //creating a brown toy dog + abstractFactory = FactoryProvider.getFactory("Toy"); + Animal toy = abstractFactory.getAnimal("Dog"); + + abstractFactory = FactoryProvider.getFactory("Color"); + Color color = abstractFactory.getColor("Brown"); + + String result = "A " + toy.getType() + " with " + color.getColor() + " color " + toy.makeSound(); + assertEquals("A Dog with brown color Barks", result); + } + +} diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/builder/BuilderPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/creational/builder/BuilderPatternIntegrationTest.java new file mode 100644 index 0000000000..898330b26e --- /dev/null +++ b/core-java/src/test/java/com/baeldung/designpatterns/creational/builder/BuilderPatternIntegrationTest.java @@ -0,0 +1,33 @@ +package com.baeldung.designpatterns.creational.builder; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class BuilderPatternIntegrationTest { + @Test + public void whenCreatingObjectThroughBuilder_thenObjectValid() { + BankAccount newAccount = new BankAccount + .BankAccountBuilder("Jon", "22738022275") + .withEmail("jon@example.com") + .wantNewsletter(true) + .build(); + + assertEquals(newAccount.getName(), "Jon"); + assertEquals(newAccount.getAccountNumber(), "22738022275"); + assertEquals(newAccount.getEmail(), "jon@example.com"); + assertEquals(newAccount.isNewsletter(), true); + } + + @Test + public void whenSkippingOptionalParameters_thenObjectValid() { + BankAccount newAccount = new BankAccount + .BankAccountBuilder("Jon", "22738022275") + .build(); + + assertEquals(newAccount.getName(), "Jon"); + assertEquals(newAccount.getAccountNumber(), "22738022275"); + assertEquals(newAccount.getEmail(), null); + assertEquals(newAccount.isNewsletter(), false); + } +} diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/factory/FactoryIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/creational/factory/FactoryIntegrationTest.java new file mode 100644 index 0000000000..ed0419c16d --- /dev/null +++ b/core-java/src/test/java/com/baeldung/designpatterns/creational/factory/FactoryIntegrationTest.java @@ -0,0 +1,32 @@ +package com.baeldung.designpatterns.creational.factory; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class FactoryIntegrationTest { + + @Test + public void whenUsingFactoryForSquare_thenCorrectObjectReturned() { + Polygon p; + PolygonFactory factory = new PolygonFactory(); + + //get the shape which has 4 sides + p = factory.getPolygon(4); + String result = "The shape with 4 sides is a " + p.getType(); + + assertEquals("The shape with 4 sides is a Square", result); + } + + @Test + public void whenUsingFactoryForOctagon_thenCorrectObjectReturned() { + Polygon p; + PolygonFactory factory = new PolygonFactory(); + + //get the shape which has 4 sides + p = factory.getPolygon(8); + String result = "The shape with 8 sides is a " + p.getType(); + + assertEquals("The shape with 8 sides is a Octagon", result); + } +} diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/singleton/SingletonIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/creational/singleton/SingletonIntegrationTest.java new file mode 100644 index 0000000000..a3d5b7a14d --- /dev/null +++ b/core-java/src/test/java/com/baeldung/designpatterns/creational/singleton/SingletonIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.designpatterns.creational.singleton; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class SingletonIntegrationTest { + + @Test + /** + * Although there is absolutely no way to determine whether + * a class is Singleton, in this test case, we will just + * check for two objects if they point to same instance or + * not. We will also check for their hashcode. + */ + public void whenGettingMultipleObjects_thenAllPointToSame() { + //first object + Singleton obj1 = Singleton.getInstance(); + + //Second object + Singleton obj2 = Singleton.getInstance(); + + assertTrue(obj1 == obj2); + assertEquals(obj1.hashCode(), obj2.hashCode()); + } + +} diff --git a/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java b/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java index da615eef6f..c27af983d3 100644 --- a/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java +++ b/core-java/src/test/java/com/baeldung/encoderdecoder/EncoderDecoderUnitTest.java @@ -1,20 +1,23 @@ package com.baeldung.encoderdecoder; +import static java.util.stream.Collectors.joining; +import static org.hamcrest.CoreMatchers.is; + +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + import org.hamcrest.CoreMatchers; import org.junit.Assert; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import java.io.UnsupportedEncodingException; -import java.net.*; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import static java.util.stream.Collectors.joining; -import static org.hamcrest.CoreMatchers.*; +import org.springframework.web.util.UriUtils; public class EncoderDecoderUnitTest { @@ -76,19 +79,20 @@ public class EncoderDecoderUnitTest { private String encodePath(String path) { try { - path = new URI(null, null, path, null).getPath(); - } catch (URISyntaxException e) { + path = UriUtils.encodePath(path, "UTF-8"); + } catch (UnsupportedEncodingException e) { LOGGER.error("Error encoding parameter {}", e.getMessage(), e); } return path; } @Test - public void givenPath_thenEncodeDecodePath() throws URISyntaxException { - URI uri = new URI(null, null, "/Path 1/Path+2", null); - - Assert.assertEquals("/Path 1/Path+2", uri.getPath()); - Assert.assertEquals("/Path%201/Path+2", uri.getRawPath()); + public void givenPathSegment_thenEncodeDecode() throws UnsupportedEncodingException { + String pathSegment = "/Path 1/Path+2"; + String encodedPathSegment = encodePath(pathSegment); + String decodedPathSegment = UriUtils.decode(encodedPathSegment, "UTF-8"); + Assert.assertEquals("/Path%201/Path+2", encodedPathSegment); + Assert.assertEquals("/Path 1/Path+2", decodedPathSegment); } @Test diff --git a/core-java/src/test/java/com/baeldung/file/FilesTest.java b/core-java/src/test/java/com/baeldung/file/FilesTest.java new file mode 100644 index 0000000000..e17e8580aa --- /dev/null +++ b/core-java/src/test/java/com/baeldung/file/FilesTest.java @@ -0,0 +1,94 @@ +package com.baeldung.file; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; + +import com.google.common.base.Charsets; +import com.google.common.io.CharSink; +import com.google.common.io.FileWriteMode; +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.util.StreamUtils; + +public class FilesTest { + + public static final String fileName = "src/main/resources/countries.properties"; + + @Before + @After + public void setup() throws Exception { + PrintWriter writer = new PrintWriter(fileName); + writer.print("UK\r\n" + "US\r\n" + "Germany\r\n"); + writer.close(); + } + + @Test + public void whenAppendToFileUsingGuava_thenCorrect() throws IOException { + File file = new File(fileName); + CharSink chs = com.google.common.io.Files.asCharSink(file, Charsets.UTF_8, FileWriteMode.APPEND); + chs.write("Spain\r\n"); + + assertThat(StreamUtils.getStringFromInputStream( + new FileInputStream(fileName))) + .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + } + + + @Test + public void whenAppendToFileUsingFiles_thenCorrect() throws IOException { + Files.write(Paths.get(fileName), "Spain\r\n".getBytes(), StandardOpenOption.APPEND); + + assertThat(StreamUtils.getStringFromInputStream( + new FileInputStream(fileName))) + .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + } + + @Test + public void whenAppendToFileUsingFileUtils_thenCorrect() throws IOException { + File file = new File(fileName); + FileUtils.writeStringToFile(file, "Spain\r\n", StandardCharsets.UTF_8, true); + + assertThat(StreamUtils.getStringFromInputStream( + new FileInputStream(fileName))) + .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + } + + @Test + public void whenAppendToFileUsingFileOutputStream_thenCorrect() throws Exception { + FileOutputStream fos = new FileOutputStream(fileName, true); + fos.write("Spain\r\n".getBytes()); + fos.close(); + + assertThat(StreamUtils.getStringFromInputStream( + new FileInputStream(fileName))) + .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + } + + @Test + public void whenAppendToFileUsingFileWriter_thenCorrect() throws IOException { + FileWriter fw = new FileWriter(fileName, true); + BufferedWriter bw = new BufferedWriter(fw); + bw.write("Spain"); + bw.newLine(); + bw.close(); + + assertThat( + StreamUtils.getStringFromInputStream( + new FileInputStream(fileName))) + .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\n"); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoIntegrationTest.java b/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoLiveTest.java similarity index 89% rename from core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoIntegrationTest.java rename to core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoLiveTest.java index fc64799578..0e1afa87a5 100644 --- a/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoIntegrationTest.java +++ b/core-java/src/test/java/com/baeldung/java/nio/selector/NioEchoLiveTest.java @@ -8,10 +8,10 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -public class NioEchoIntegrationTest { +public class NioEchoLiveTest { - Process server; - EchoClient client; + private Process server; + private EchoClient client; @Before public void setup() throws IOException, InterruptedException { diff --git a/core-java/src/test/java/com/baeldung/javanetworking/uriurl/URIvsURLUnitTest.java b/core-java/src/test/java/com/baeldung/javanetworking/uriurl/URIvsURLUnitTest.java index ed36951f73..8837dc5556 100644 --- a/core-java/src/test/java/com/baeldung/javanetworking/uriurl/URIvsURLUnitTest.java +++ b/core-java/src/test/java/com/baeldung/javanetworking/uriurl/URIvsURLUnitTest.java @@ -71,8 +71,5 @@ public class URIvsURLUnitTest { URL url = new URL("http://courses.baeldung.com"); String contents = IOUtils.toString(url.openStream()); - - assertTrue(contents.contains("")); - } - + } } diff --git a/core-java/src/test/java/com/baeldung/jdbc/JdbcIntegrationTest.java b/core-java/src/test/java/com/baeldung/jdbc/JdbcLiveTest.java similarity index 97% rename from core-java/src/test/java/com/baeldung/jdbc/JdbcIntegrationTest.java rename to core-java/src/test/java/com/baeldung/jdbc/JdbcLiveTest.java index 926fdb3833..da0c6bffe5 100644 --- a/core-java/src/test/java/com/baeldung/jdbc/JdbcIntegrationTest.java +++ b/core-java/src/test/java/com/baeldung/jdbc/JdbcLiveTest.java @@ -21,9 +21,9 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -public class JdbcIntegrationTest { +public class JdbcLiveTest { - private static final Logger LOG = Logger.getLogger(JdbcIntegrationTest.class); + private static final Logger LOG = Logger.getLogger(JdbcLiveTest.class); private Connection con; diff --git a/core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetTest.java b/core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetTest.java new file mode 100644 index 0000000000..cb455c213a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetTest.java @@ -0,0 +1,157 @@ +package com.baeldung.jdbcrowset; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.FilteredRowSet; +import javax.sql.rowset.JdbcRowSet; +import javax.sql.rowset.JoinRowSet; +import javax.sql.rowset.RowSetFactory; +import javax.sql.rowset.RowSetProvider; +import javax.sql.rowset.WebRowSet; + +import org.junit.Before; +import org.junit.Test; + +import com.sun.rowset.CachedRowSetImpl; +import com.sun.rowset.JdbcRowSetImpl; +import com.sun.rowset.JoinRowSetImpl; +import com.sun.rowset.WebRowSetImpl; + +public class JdbcRowSetTest { + Statement stmt = null; + String username = "sa"; + String password = ""; + String url = "jdbc:h2:mem:testdb"; + String sql = "SELECT * FROM customers"; + + @Before + public void setup() throws Exception { + Connection conn = DatabaseConfiguration.geth2Connection(); + + String drop = "DROP TABLE IF EXISTS customers, associates;"; + String schema = "CREATE TABLE customers (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id)); "; + String schemapartb = "CREATE TABLE associates (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id));"; + stmt = conn.createStatement(); + stmt.executeUpdate(drop); + stmt.executeUpdate(schema); + stmt.executeUpdate(schemapartb); + DatabaseConfiguration.initDatabase(stmt); + + } + + // JdbcRowSet Example + @Test + public void createJdbcRowSet_SelectCustomers_ThenCorrect() throws Exception { + + String sql = "SELECT * FROM customers"; + JdbcRowSet jdbcRS; + Connection conn = DatabaseConfiguration.geth2Connection(); + jdbcRS = new JdbcRowSetImpl(conn); + jdbcRS.setType(ResultSet.TYPE_SCROLL_INSENSITIVE); + jdbcRS.setCommand(sql); + jdbcRS.execute(); + jdbcRS.addRowSetListener(new ExampleListener()); + + while (jdbcRS.next()) { + // each call to next, generates a cursorMoved event + System.out.println("id=" + jdbcRS.getString(1)); + System.out.println("name=" + jdbcRS.getString(2)); + } + + } + + // CachedRowSet Example + @Test + public void createCachedRowSet_DeleteRecord_ThenCorrect() throws Exception { + + CachedRowSet crs = new CachedRowSetImpl(); + crs.setUsername(username); + crs.setPassword(password); + crs.setUrl(url); + crs.setCommand(sql); + crs.execute(); + crs.addRowSetListener(new ExampleListener()); + while (crs.next()) { + if (crs.getInt("id") == 1) { + System.out.println("CRS found customer1 and will remove the record."); + crs.deleteRow(); + break; + } + } + } + + // WebRowSet example + @Test + public void createWebRowSet_SelectCustomers_WritetoXML_ThenCorrect() throws SQLException, IOException { + + WebRowSet wrs = new WebRowSetImpl(); + wrs.setUsername(username); + wrs.setPassword(password); + wrs.setUrl(url); + wrs.setCommand(sql); + wrs.execute(); + FileOutputStream ostream = new FileOutputStream("customers.xml"); + wrs.writeXml(ostream); + } + + // JoinRowSet example + @Test + public void createCachedRowSets_DoJoinRowSet_ThenCorrect() throws Exception { + + CachedRowSetImpl customers = new CachedRowSetImpl(); + customers.setUsername(username); + customers.setPassword(password); + customers.setUrl(url); + customers.setCommand(sql); + customers.execute(); + + CachedRowSetImpl associates = new CachedRowSetImpl(); + associates.setUsername(username); + associates.setPassword(password); + associates.setUrl(url); + String associatesSQL = "SELECT * FROM associates"; + associates.setCommand(associatesSQL); + associates.execute(); + + JoinRowSet jrs = new JoinRowSetImpl(); + final String ID = "id"; + final String NAME = "name"; + jrs.addRowSet(customers, ID); + jrs.addRowSet(associates, ID); + jrs.last(); + System.out.println("Total rows: " + jrs.getRow()); + jrs.beforeFirst(); + while (jrs.next()) { + + String string1 = jrs.getString(ID); + String string2 = jrs.getString(NAME); + System.out.println("ID: " + string1 + ", NAME: " + string2); + } + } + + // FilteredRowSet example + @Test + public void createFilteredRowSet_filterByRegexExpression_thenCorrect() throws Exception { + RowSetFactory rsf = RowSetProvider.newFactory(); + FilteredRowSet frs = rsf.createFilteredRowSet(); + frs.setCommand("select * from customers"); + Connection conn = DatabaseConfiguration.geth2Connection(); + frs.execute(conn); + frs.setFilter(new FilterExample("^[A-C].*")); + + ResultSetMetaData rsmd = frs.getMetaData(); + int columncount = rsmd.getColumnCount(); + while (frs.next()) { + for (int i = 1; i <= columncount; i++) { + System.out.println(rsmd.getColumnLabel(i) + " = " + frs.getObject(i) + " "); + } + } + } +} diff --git a/core-java/src/test/java/com/baeldung/loops/WhenUsingLoops.java b/core-java/src/test/java/com/baeldung/loops/WhenUsingLoops.java new file mode 100644 index 0000000000..f82f9ddaa7 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/loops/WhenUsingLoops.java @@ -0,0 +1,107 @@ +package com.baeldung.loops; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class WhenUsingLoops { + + private LoopsInJava loops = new LoopsInJava(); + private static List list = new ArrayList<>(); + private static Set set = new HashSet<>(); + private static Map map = new HashMap<>(); + + @BeforeClass + public static void setUp() { + list.add("One"); + list.add("Two"); + list.add("Three"); + + set.add("Four"); + set.add("Five"); + set.add("Six"); + + map.put("One", 1); + map.put("Two", 2); + map.put("Three", 3); + } + + @Test + public void shouldRunForLoop() { + int[] expected = { 0, 1, 2, 3, 4 }; + int[] actual = loops.simple_for_loop(); + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void shouldRunEnhancedForeachLoop() { + int[] expected = { 0, 1, 2, 3, 4 }; + int[] actual = loops.enhanced_for_each_loop(); + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void shouldRunWhileLoop() { + int[] expected = { 0, 1, 2, 3, 4 }; + int[] actual = loops.while_loop(); + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void shouldRunDoWhileLoop() { + int[] expected = { 0, 1, 2, 3, 4 }; + int[] actual = loops.do_while_loop(); + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void whenUsingSimpleFor_shouldIterateList() { + for (int i = 0; i < list.size(); i++) { + System.out.println(list.get(i)); + } + } + + @Test + public void whenUsingEnhancedFor_shouldIterateList() { + for (String item : list) { + System.out.println(item); + } + } + + @Test + public void whenUsingEnhancedFor_shouldIterateSet() { + for (String item : set) { + System.out.println(item); + } + } + + @Test + public void whenUsingEnhancedFor_shouldIterateMap() { + for (Entry entry : map.entrySet()) { + System.out.println("Key: " + entry.getKey() + " - " + "Value: " + entry.getValue()); + } + } + + @Test + public void whenUsingSimpleFor_shouldRunLabelledLoop() { + aa: for (int i = 1; i <= 3; i++) { + if (i == 1) + continue; + bb: for (int j = 1; j <= 3; j++) { + if (i == 2 && j == 2) { + break aa; + } + System.out.println(i + " " + j); + } + } + } + +} diff --git a/core-java/src/test/java/com/baeldung/nestedclass/AnonymousInner.java b/core-java/src/test/java/com/baeldung/nestedclass/AnonymousInner.java new file mode 100644 index 0000000000..9fa8ee9cd5 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nestedclass/AnonymousInner.java @@ -0,0 +1,20 @@ +package com.baeldung.nestedclass; + +import org.junit.Test; + +abstract class SimpleAbstractClass { + abstract void run(); +} + +public class AnonymousInner { + + @Test + public void run() { + SimpleAbstractClass simpleAbstractClass = new SimpleAbstractClass() { + void run() { + System.out.println("Running Anonymous Class..."); + } + }; + simpleAbstractClass.run(); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/nestedclass/Enclosing.java b/core-java/src/test/java/com/baeldung/nestedclass/Enclosing.java new file mode 100644 index 0000000000..3db33cde9b --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nestedclass/Enclosing.java @@ -0,0 +1,21 @@ +package com.baeldung.nestedclass; + +import org.junit.Test; + +public class Enclosing { + + private static int x = 1; + + public static class StaticNested { + + private void run() { + System.out.println("x = " + x); + } + } + + @Test + public void test() { + Enclosing.StaticNested nested = new Enclosing.StaticNested(); + nested.run(); + } +} diff --git a/core-java/src/test/java/com/baeldung/nestedclass/NewEnclosing.java b/core-java/src/test/java/com/baeldung/nestedclass/NewEnclosing.java new file mode 100644 index 0000000000..deeb72de0c --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nestedclass/NewEnclosing.java @@ -0,0 +1,22 @@ +package com.baeldung.nestedclass; + +import org.junit.Test; + +public class NewEnclosing { + + private void run() { + class Local { + void run() { + System.out.println("Welcome to Baeldung!"); + } + } + Local local = new Local(); + local.run(); + } + + @Test + public void test() { + NewEnclosing newEnclosing = new NewEnclosing(); + newEnclosing.run(); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/nestedclass/NewOuter.java b/core-java/src/test/java/com/baeldung/nestedclass/NewOuter.java new file mode 100644 index 0000000000..a3a723b30e --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nestedclass/NewOuter.java @@ -0,0 +1,30 @@ +package com.baeldung.nestedclass; + +import org.junit.Test; + +public class NewOuter { + + int a = 1; + static int b = 2; + + public class InnerClass { + int a = 3; + static final int b = 4; + + public void run() { + System.out.println("a = " + a); + System.out.println("b = " + b); + System.out.println("NewOuterTest.this.a = " + NewOuter.this.a); + System.out.println("NewOuterTest.b = " + NewOuter.b); + System.out.println("NewOuterTest.this.b = " + NewOuter.this.b); + } + } + + @Test + public void test() { + NewOuter outer = new NewOuter(); + NewOuter.InnerClass inner = outer.new InnerClass(); + inner.run(); + + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/nestedclass/Outer.java b/core-java/src/test/java/com/baeldung/nestedclass/Outer.java new file mode 100644 index 0000000000..d5e46670c9 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nestedclass/Outer.java @@ -0,0 +1,20 @@ +package com.baeldung.nestedclass; + +import org.junit.Test; + +public class Outer { + + public class Inner { + + public void run() { + System.out.println("Calling test..."); + } + } + + @Test + public void test() { + Outer outer = new Outer(); + Outer.Inner inner = outer.new Inner(); + inner.run(); + } +} diff --git a/core-java/src/test/java/com/baeldung/networking/udp/UDPIntegrationTest.java b/core-java/src/test/java/com/baeldung/networking/udp/UDPLiveTest.java similarity index 96% rename from core-java/src/test/java/com/baeldung/networking/udp/UDPIntegrationTest.java rename to core-java/src/test/java/com/baeldung/networking/udp/UDPLiveTest.java index 968c01d24e..7337be6e3d 100644 --- a/core-java/src/test/java/com/baeldung/networking/udp/UDPIntegrationTest.java +++ b/core-java/src/test/java/com/baeldung/networking/udp/UDPLiveTest.java @@ -9,7 +9,7 @@ import java.io.IOException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -public class UDPIntegrationTest { +public class UDPLiveTest { private EchoClient client; @Before diff --git a/core-java/src/test/java/com/baeldung/networking/udp/broadcast/BroadcastIntegrationTest.java b/core-java/src/test/java/com/baeldung/networking/udp/broadcast/BroadcastLiveTest.java similarity index 96% rename from core-java/src/test/java/com/baeldung/networking/udp/broadcast/BroadcastIntegrationTest.java rename to core-java/src/test/java/com/baeldung/networking/udp/broadcast/BroadcastLiveTest.java index c4f1e1f42c..51e5bfc669 100644 --- a/core-java/src/test/java/com/baeldung/networking/udp/broadcast/BroadcastIntegrationTest.java +++ b/core-java/src/test/java/com/baeldung/networking/udp/broadcast/BroadcastLiveTest.java @@ -7,7 +7,7 @@ import java.io.IOException; import static org.junit.Assert.assertEquals; -public class BroadcastIntegrationTest { +public class BroadcastLiveTest { private BroadcastingClient client; @Test diff --git a/core-java/src/test/java/com/baeldung/networking/udp/multicast/MulticastIntegrationTest.java b/core-java/src/test/java/com/baeldung/networking/udp/multicast/MulticastLiveTest.java similarity index 96% rename from core-java/src/test/java/com/baeldung/networking/udp/multicast/MulticastIntegrationTest.java rename to core-java/src/test/java/com/baeldung/networking/udp/multicast/MulticastLiveTest.java index 404f6c4e85..83d0482f44 100644 --- a/core-java/src/test/java/com/baeldung/networking/udp/multicast/MulticastIntegrationTest.java +++ b/core-java/src/test/java/com/baeldung/networking/udp/multicast/MulticastLiveTest.java @@ -7,7 +7,7 @@ import java.io.IOException; import static org.junit.Assert.assertEquals; -public class MulticastIntegrationTest { +public class MulticastLiveTest { private MulticastingClient client; @Test diff --git a/core-java/src/test/java/com/baeldung/polymorphism/PolymorphismUnitTest.java b/core-java/src/test/java/com/baeldung/polymorphism/PolymorphismUnitTest.java new file mode 100644 index 0000000000..8fb606c2fc --- /dev/null +++ b/core-java/src/test/java/com/baeldung/polymorphism/PolymorphismUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.polymorphism; + +import static org.junit.Assert.*; + +import java.awt.image.BufferedImage; + +import org.junit.Ignore; +import org.junit.Test; + +public class PolymorphismUnitTest { + + @Test + public void givenImageFile_whenFileCreated_shouldSucceed() { + ImageFile imageFile = FileManager.createImageFile("SampleImageFile", 200, 100, new BufferedImage(100, 200, BufferedImage.TYPE_INT_RGB).toString() + .getBytes(), "v1.0.0"); + assertEquals(200, imageFile.getHeight()); + } + + // Downcasting then Upcasting + @Test + public void givenTextFile_whenTextFileCreatedAndAssignedToGenericFileAndCastBackToTextFileOnGetWordCount_shouldSucceed() { + GenericFile textFile = FileManager.createTextFile("SampleTextFile", "This is a sample text content", "v1.0.0"); + TextFile textFile2 = (TextFile) textFile; + assertEquals(6, textFile2.getWordCount()); + } + + // Downcasting + @Test(expected = ClassCastException.class) + public void givenGenericFile_whenCastToTextFileAndInvokeGetWordCount_shouldFail() { + GenericFile genericFile = new GenericFile(); + TextFile textFile = (TextFile) genericFile; + System.out.println(textFile.getWordCount()); + } +} diff --git a/core-java/src/test/java/com/baeldung/printscreen/ScreenshotIntegrationTest.java b/core-java/src/test/java/com/baeldung/printscreen/ScreenshotLiveTest.java similarity index 92% rename from core-java/src/test/java/com/baeldung/printscreen/ScreenshotIntegrationTest.java rename to core-java/src/test/java/com/baeldung/printscreen/ScreenshotLiveTest.java index 13609b6977..672ba9668d 100644 --- a/core-java/src/test/java/com/baeldung/printscreen/ScreenshotIntegrationTest.java +++ b/core-java/src/test/java/com/baeldung/printscreen/ScreenshotLiveTest.java @@ -7,7 +7,7 @@ import java.io.File; import static org.junit.Assert.assertTrue; -public class ScreenshotIntegrationTest { +public class ScreenshotLiveTest { private Screenshot screenshot = new Screenshot("Screenshot.jpg"); private File file = new File("Screenshot.jpg"); diff --git a/core-java/src/test/java/com/baeldung/stack/StackUnitTest.java b/core-java/src/test/java/com/baeldung/stack/StackUnitTest.java new file mode 100644 index 0000000000..2b04617f36 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/stack/StackUnitTest.java @@ -0,0 +1,137 @@ +package com.baeldung.stack; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.List; +import java.util.ListIterator; +import java.util.Stack; + +import org.junit.Test; +public class StackUnitTest { + + @Test + public void whenStackIsCreated_thenItHasSize0() { + Stack intStack = new Stack(); + assertEquals(0, intStack.size()); + } + + @Test + public void givenEmptyStack_whenElementIsPushed_thenStackSizeisIncreased() { + Stack intStack = new Stack(); + intStack.push(1); + assertEquals(1, intStack.size()); + } + + @Test + public void givenEmptyStack_whenMultipleElementsArePushed_thenStackSizeisIncreased() { + Stack intStack = new Stack(); + List intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7); + boolean result = intStack.addAll(intList); + assertTrue(result); + assertEquals(7, intList.size()); + } + + @Test + public void whenElementIsPoppedFromStack_thenElementIsRemovedAndSizeChanges() { + Stack intStack = new Stack(); + intStack.push(5); + intStack.pop(); + assertTrue(intStack.isEmpty()); + } + + @Test + public void whenElementIsPeeked_thenElementIsNotRemovedAndSizeDoesNotChange() { + Stack intStack = new Stack(); + intStack.push(5); + intStack.peek(); + assertEquals(1, intStack.search(5)); + assertEquals(1, intStack.size()); + } + + @Test + public void whenElementIsOnStack_thenSearchReturnsItsDistanceFromTheTop() { + Stack intStack = new Stack(); + intStack.push(5); + assertEquals(1, intStack.search(5)); + } + + @Test + public void whenElementIsOnStack_thenIndexOfReturnsItsIndex() { + Stack intStack = new Stack(); + intStack.push(5); + int indexOf = intStack.indexOf(5); + assertEquals(0, indexOf); + } + + @Test + public void whenMultipleElementsAreOnStack_thenIndexOfReturnsLastElementIndex() { + Stack intStack = new Stack(); + intStack.push(5); + intStack.push(5); + intStack.push(5); + int lastIndexOf = intStack.lastIndexOf(5); + assertEquals(2, lastIndexOf); + } + + @Test + public void givenElementOnStack_whenRemoveElementIsInvoked_thenElementIsRemoved() { + Stack intStack = new Stack(); + intStack.push(5); + intStack.push(5); + intStack.removeElement(5); + assertEquals(1, intStack.size()); + } + + @Test + public void givenElementOnStack_whenRemoveElementAtIsInvoked_thenElementIsRemoved() { + Stack intStack = new Stack(); + intStack.push(5); + intStack.push(7); + intStack.removeElementAt(1); + assertEquals(-1, intStack.search(7)); + } + + @Test + public void givenElementsOnStack_whenRemoveAllElementsIsInvoked_thenAllElementsAreRemoved() { + Stack intStack = new Stack(); + intStack.push(5); + intStack.push(7); + intStack.removeAllElements(); + assertTrue(intStack.isEmpty()); + } + + @Test + public void givenElementsOnStack_whenRemoveAllIsInvoked_thenAllElementsFromCollectionAreRemoved() { + Stack intStack = new Stack(); + List intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7); + intStack.addAll(intList); + intStack.add(500); + intStack.removeAll(intList); + assertEquals(1, intStack.size()); + } + + @Test + public void givenElementsOnStack_whenRemoveIfIsInvoked_thenAllElementsSatysfyingConditionAreRemoved() { + Stack intStack = new Stack(); + List intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7); + intStack.addAll(intList); + intStack.removeIf(element -> element < 6); + assertEquals(2, intStack.size()); + } + + @Test + public void whenAnotherStackCreatedWhileTraversingStack_thenStacksAreEqual() { + Stack intStack = new Stack<>(); + List intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7); + intStack.addAll(intList); + ListIterator it = intStack.listIterator(); + Stack result = new Stack(); + while(it.hasNext()) { + result.push(it.next()); + } + + assertThat(result, equalTo(intStack)); + } +} diff --git a/core-java/src/test/java/com/baeldung/staticdemo/CarIntegrationTest.java b/core-java/src/test/java/com/baeldung/staticdemo/CarIntegrationTest.java new file mode 100644 index 0000000000..3150627269 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/staticdemo/CarIntegrationTest.java @@ -0,0 +1,14 @@ +package com.baeldung.staticdemo; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class CarIntegrationTest { + @Test + public void whenNumberOfCarObjectsInitialized_thenStaticCounterIncreases() { + new Car("Jaguar", "V8"); + new Car("Bugatti", "W16"); + assertEquals(2, Car.numberOfCars); + } +} diff --git a/core-java/src/test/java/com/baeldung/staticdemo/SingletonIntegrationTest.java b/core-java/src/test/java/com/baeldung/staticdemo/SingletonIntegrationTest.java new file mode 100644 index 0000000000..28d864073a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/staticdemo/SingletonIntegrationTest.java @@ -0,0 +1,15 @@ +package com.baeldung.staticdemo; + +import org.junit.Assert; +import org.junit.Test; + +public class SingletonIntegrationTest { + + @Test + public void givenStaticInnerClass_whenMultipleTimesInstanceCalled_thenOnlyOneTimeInitialized() { + Singleton object1 = Singleton.getInstance(); + Singleton object2 = Singleton.getInstance(); + + Assert.assertSame(object1, object2); + } +} diff --git a/core-java/src/test/java/com/baeldung/staticdemo/StaticBlockIntegrationTest.java b/core-java/src/test/java/com/baeldung/staticdemo/StaticBlockIntegrationTest.java new file mode 100644 index 0000000000..f98e3e14db --- /dev/null +++ b/core-java/src/test/java/com/baeldung/staticdemo/StaticBlockIntegrationTest.java @@ -0,0 +1,17 @@ +package com.baeldung.staticdemo; + +import static org.hamcrest.collection.IsIterableContainingInOrder.contains; +import static org.junit.Assert.assertThat; + +import java.util.List; + +import org.junit.Test; + +public class StaticBlockIntegrationTest { + + @Test + public void whenAddedListElementsThroughStaticBlock_thenEnsureCorrectOrder() { + List actualList = StaticBlock.getRanks(); + assertThat(actualList, contains("Lieutenant", "Captain", "Major", "Colonel", "General")); + } +} diff --git a/core-java/src/test/java/com/baeldung/stream/StreamIndicesTest.java b/core-java/src/test/java/com/baeldung/stream/StreamIndicesTest.java index d8513417ea..a02ef4031e 100644 --- a/core-java/src/test/java/com/baeldung/stream/StreamIndicesTest.java +++ b/core-java/src/test/java/com/baeldung/stream/StreamIndicesTest.java @@ -1,19 +1,18 @@ package com.baeldung.stream; -import static org.junit.Assert.assertEquals; +import com.codepoetics.protonpack.Indexed; +import org.junit.Test; import java.util.Arrays; import java.util.List; -import org.junit.Test; - -import com.codepoetics.protonpack.Indexed; +import static org.junit.Assert.assertEquals; public class StreamIndicesTest { @Test - public void givenArray_whenGetIndexedStrings_thenReturnListOfEvenIndexedStrings() { - String[] names = { "Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim" }; + public void whenCalled_thenReturnListOfEvenIndexedStrings() { + String[] names = {"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"}; List expectedResult = Arrays.asList("Afrim", "Besim", "Durim"); List actualResult = StreamIndices.getEvenIndexedStrings(names); @@ -21,8 +20,8 @@ public class StreamIndicesTest { } @Test - public void givenArray_whenGetIndexedStrings_thenReturnListOfEvenIndexedStringsVersionTwo() { - String[] names = { "Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim" }; + public void whenCalled_thenReturnListOfEvenIndexedStringsVersionTwo() { + String[] names = {"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"}; List expectedResult = Arrays.asList("Afrim", "Besim", "Durim"); List actualResult = StreamIndices.getEvenIndexedStrings(names); @@ -30,8 +29,8 @@ public class StreamIndicesTest { } @Test - public void givenArray_whenGetIndexedStrings_thenReturnListOfOddStrings() { - String[] names = { "Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim" }; + public void whenCalled_thenReturnListOfOddStrings() { + String[] names = {"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"}; List expectedResult = Arrays.asList("Bashkim", "Lulzim", "Shpetim"); List actualResult = StreamIndices.getOddIndexedStrings(names); @@ -39,30 +38,33 @@ public class StreamIndicesTest { } @Test - public void givenList_whenGetIndexedStrings_thenReturnListOfEvenIndexedStrings() { + public void givenList_whenCalled_thenReturnListOfEvenIndexedStrings() { List names = Arrays.asList("Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"); - List> expectedResult = Arrays.asList(Indexed.index(0, "Afrim"), Indexed.index(2, "Besim"), Indexed.index(4, "Durim")); + List> expectedResult = Arrays + .asList(Indexed.index(0, "Afrim"), Indexed.index(2, "Besim"), Indexed + .index(4, "Durim")); List> actualResult = StreamIndices.getEvenIndexedStrings(names); assertEquals(expectedResult, actualResult); } @Test - public void givenList_whenGetIndexedStrings_thenReturnListOfOddIndexedStrings() { + public void givenList_whenCalled_thenReturnListOfOddIndexedStrings() { List names = Arrays.asList("Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"); - List> expectedResult = Arrays.asList(Indexed.index(1, "Bashkim"), Indexed.index(3, "Lulzim"), Indexed.index(5, "Shpetim")); + List> expectedResult = Arrays + .asList(Indexed.index(1, "Bashkim"), Indexed.index(3, "Lulzim"), Indexed + .index(5, "Shpetim")); List> actualResult = StreamIndices.getOddIndexedStrings(names); assertEquals(expectedResult, actualResult); } @Test - public void givenArray_whenGetIndexedStrings_thenReturnListOfOddStringsVersionTwo() { - String[] names = { "Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim" }; + public void whenCalled_thenReturnListOfOddStringsVersionTwo() { + String[] names = {"Afrim", "Bashkim", "Besim", "Lulzim", "Durim", "Shpetim"}; List expectedResult = Arrays.asList("Bashkim", "Lulzim", "Shpetim"); List actualResult = StreamIndices.getOddIndexedStringsVersionTwo(names); assertEquals(expectedResult, actualResult); } - } \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/string/StringTest.java b/core-java/src/test/java/com/baeldung/string/StringTest.java new file mode 100644 index 0000000000..e88b2d7c2c --- /dev/null +++ b/core-java/src/test/java/com/baeldung/string/StringTest.java @@ -0,0 +1,226 @@ +package com.baeldung.string; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.util.IllegalFormatException; +import java.util.regex.PatternSyntaxException; + +import org.junit.Test; + +public class StringTest { + + @Test + public void whenCallCodePointAt_thenDecimalUnicodeReturned() { + assertEquals(97, "abcd".codePointAt(0)); + } + + @Test(expected = StringIndexOutOfBoundsException.class) + public void whenPassNonExistingIndex_thenExceptionThrown() { + int a = "abcd".codePointAt(4); + } + + @Test + public void whenCallConcat_thenCorrect() { + assertEquals("elephant", "elep".concat("hant")); + } + + @Test + public void whenGetBytes_thenCorrect() throws UnsupportedEncodingException { + byte[] byteArray1 = "abcd".getBytes(); + byte[] byteArray2 = "efgh".getBytes(StandardCharsets.US_ASCII); + byte[] byteArray3 = "ijkl".getBytes("UTF-8"); + byte[] expected1 = new byte[] { 97, 98, 99, 100 }; + byte[] expected2 = new byte[] { 101, 102, 103, 104 }; + byte[] expected3 = new byte[] { 105, 106, 107, 108 }; + + assertArrayEquals(expected1, byteArray1); + assertArrayEquals(expected2, byteArray2); + assertArrayEquals(expected3, byteArray3); + } + + @Test + public void whenGetBytesUsingASCII_thenCorrect() { + byte[] byteArray = "efgh".getBytes(StandardCharsets.US_ASCII); + byte[] expected = new byte[] { 101, 102, 103, 104 }; + + assertArrayEquals(expected, byteArray); + } + + @Test + public void whenCreateStringUsingByteArray_thenCorrect() { + byte[] array = new byte[] { 97, 98, 99, 100 }; + String s = new String(array); + + assertEquals("abcd", s); + } + + @Test + public void whenCallCharAt_thenCorrect() { + assertEquals('P', "Paul".charAt(0)); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void whenCharAtOnNonExistingIndex_thenIndexOutOfBoundsExceptionThrown() { + char character = "Paul".charAt(4); + } + + @Test + public void whenCallCodePointCount_thenCorrect() { + assertEquals(2, "abcd".codePointCount(0, 2)); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void whenSecondIndexEqualToLengthOfString_thenIndexOutOfBoundsExceptionThrown() { + char character = "Paul".charAt(4); + } + + @Test + public void whenCallContains_thenCorrect() { + String s = "abcd"; + + assertTrue(s.contains("abc")); + assertFalse(s.contains("cde")); + } + + @Test + public void whenCallCopyValueOf_thenStringConstructed() { + char[] array = new char[] { 'a', 'b', 'c', 'd' }; + + assertEquals("abcd", String.copyValueOf(array)); + } + + @Test + public void whenCallEndsWith_thenCorrect() { + String s1 = "test"; + + assertTrue(s1.endsWith("t")); + } + + @Test + public void whenFormat_thenCorrect() { + String value = "Baeldung"; + String formatted = String.format("Welcome to %s!", value); + + assertEquals("Welcome to Baeldung!", formatted); + } + + @Test(expected = IllegalFormatException.class) + public void whenInvalidFormatSyntax_thenIllegalFormatExceptionThrown() { + String value = "Baeldung"; + String formatted = String.format("Welcome to %x!", value); + } + + @Test + public void whenCallIndexOf_thenCorrect() { + assertEquals(1, "foo".indexOf("o")); + } + + @Test + public void whenCallIsEmpty_thenCorrect() { + String s1 = ""; + + assertTrue(s1.isEmpty()); + } + + @Test + public void whenCallLastIndexOf_thenCorrect() { + assertEquals(2, "foo".lastIndexOf("o")); + assertEquals(2, "foo".lastIndexOf(111)); + } + + @Test + public void whenCallRegionMatches_thenCorrect() { + assertTrue("welcome to baeldung".regionMatches(false, 11, "baeldung", 0, 8)); + } + + @Test + public void whenCallStartsWith_thenCorrect() { + assertTrue("foo".startsWith("f")); + } + + @Test + public void whenTrim_thenCorrect() { + assertEquals("foo", " foo ".trim()); + } + + @Test + public void whenSplit_thenCorrect() { + String s = "Welcome to Baeldung"; + String[] array = new String[] { "Welcome", "to", "Baeldung" }; + + assertArrayEquals(array, s.split(" ")); + } + + @Test(expected = PatternSyntaxException.class) + public void whenPassInvalidParameterToSplit_thenPatternSyntaxExceptionThrown() { + String s = "Welcome*to Baeldung"; + + String[] result = s.split("*"); + } + + @Test + public void whenCallSubSequence_thenCorrect() { + String s = "Welcome to Baeldung"; + + assertEquals("Welcome", s.subSequence(0, 7)); + } + + @Test + public void whenCallSubstring_thenCorrect() { + String s = "Welcome to Baeldung"; + + assertEquals("Welcome", s.substring(0, 7)); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void whenSecondIndexEqualToLengthOfString_thenCorrect() { + String s = "Welcome to Baeldung"; + + String sub = s.substring(0, 20); + } + + @Test + public void whenConvertToUpperCase_thenCorrect() { + String s = "Welcome to Baeldung!"; + + assertEquals("WELCOME TO BAELDUNG!", s.toUpperCase()); + } + + @Test + public void whenConvertToLowerCase_thenCorrect() { + String s = "WELCOME to BAELDUNG!"; + + assertEquals("welcome to baeldung!", s.toLowerCase()); + } + + @Test + public void whenCallReplace_thenCorrect() { + String s = "I learn Spanish"; + + assertEquals("I learn French", s.replaceAll("Spanish", "French")); + } + + @Test + public void whenIntern_thenCorrect() { + String s1 = "abc"; + String s2 = new String("abc"); + String s3 = new String("foo"); + String s4 = s1.intern(); + String s5 = s2.intern(); + + assertFalse(s3 == s4); + assertTrue(s1 == s5); + } + + @Test + public void whenCallValueOf_thenCorrect() { + long l = 200L; + + assertEquals("200", String.valueOf(l)); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/string/formatter/StringFormatterExampleTests.java b/core-java/src/test/java/com/baeldung/string/formatter/StringFormatterExampleTests.java new file mode 100644 index 0000000000..ad4f5dce7e --- /dev/null +++ b/core-java/src/test/java/com/baeldung/string/formatter/StringFormatterExampleTests.java @@ -0,0 +1,141 @@ +package com.baeldung.string.formatter; + +import java.util.Calendar; +import java.util.Formatter; +import java.util.GregorianCalendar; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class StringFormatterExampleTests { + + @Test + public void givenString_whenFormatSpecifierForCalendar_thenGotExpected() { + //Syntax of Format Specifiers for Date/Time Representation + Calendar c = new GregorianCalendar(2017, 11, 10); + String s = String.format("The date is: %tm %1$te,%1$tY", c); + + + assertEquals("The date is: 12 10,2017", s); + } + + @Test + public void givenString_whenGeneralConversion_thenConvertedString() { + //General Conversions + String s = String.format("The correct answer is %s", false); + assertEquals("The correct answer is false", s); + + s = String.format("The correct answer is %b", null); + assertEquals("The correct answer is false", s); + + s = String.format("The correct answer is %B", true); + assertEquals("The correct answer is TRUE", s); + } + + @Test + public void givenString_whenCharConversion_thenConvertedString() { + //Character Conversions + String s = String.format("The correct answer is %c", 'a'); + assertEquals("The correct answer is a", s); + + s = String.format("The correct answer is %c", null); + assertEquals("The correct answer is null", s); + + s = String.format("The correct answer is %C", 'b'); + assertEquals("The correct answer is B", s); + + s = String.format("The valid unicode character: %c", 0x0400); + assertTrue(Character.isValidCodePoint(0x0400)); + assertEquals("The valid unicode character: Ѐ", s); + } + + @Test(expected = java.util.IllegalFormatCodePointException.class) + public void givenString_whenIllegalCodePointForConversion_thenError() { + String s = String.format("The valid unicode character: %c", 0x11FFFF); + assertFalse(Character.isValidCodePoint(0x11FFFF)); + assertEquals("The valid unicode character: Ā", s); + } + + @Test + public void givenString_whenNumericIntegralConversion_thenConvertedString() { + //Numeric Integral Conversions + String s = String.format("The number 25 in decimal = %d", 25); + assertEquals("The number 25 in decimal = 25", s); + + s = String.format("The number 25 in octal = %o", 25); + assertEquals("The number 25 in octal = 31", s); + + s = String.format("The number 25 in hexadecimal = %x", 25); + assertEquals("The number 25 in hexadecimal = 19", s); + } + + @Test + public void givenString_whenNumericFloatingConversion_thenConvertedString() { + //Numeric Floating-point Conversions + String s = String.format("The computerized scientific format of 10000.00 " + + "= %e", 10000.00); + assertEquals("The computerized scientific format of 10000.00 = 1.000000e+04", s); + + s = String.format("The decimal format of 10.019 = %f", 10.019); + assertEquals("The decimal format of 10.019 = 10.019000", s); + } + + @Test + public void givenString_whenLineSeparatorConversion_thenConvertedString() { + //Line Separator Conversion + String s = String.format("First Line %nSecond Line"); + assertEquals("First Line " + System.getProperty("line.separator") + + "Second Line", s); + } + + @Test + public void givenString_whenSpecifyFlag_thenGotFormattedString() { + //Without left-justified flag + String s = String.format("Without left justified flag: %5d", 25); + assertEquals("Without left justified flag: 25", s); + + //Using left-justified flag + s = String.format("With left justified flag: %-5d", 25); + assertEquals("With left justified flag: 25 ", s); + } + + @Test + public void givenString_whenSpecifyPrecision_thenGotExpected() { + + //Precision + String s = String.format("Output of 25.09878 with Precision 2: %.2f", 25.09878); + assertEquals("Output of 25.09878 with Precision 2: 25.10", s); + + s = String.format("Output of general conversion type with Precision 2: %.2b", true); + assertEquals("Output of general conversion type with Precision 2: tr", s); + } + + @Test + public void givenString_whenSpecifyArgumentIndex_thenGotExpected() { + Calendar c = new GregorianCalendar(2017, 11, 10); + //Argument_Index + String s = String.format("The date is: %tm %1$te,%1$tY", c); + assertEquals("The date is: 12 10,2017", s); + + s = String.format("The date is: %tm % implements Vehicle { + +} diff --git a/core-java/src/test/java/org/baeldung/java/diamond/DiamondOperatorUnitTest.java b/core-java/src/test/java/org/baeldung/java/diamond/DiamondOperatorUnitTest.java new file mode 100644 index 0000000000..f6c7f7162f --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/diamond/DiamondOperatorUnitTest.java @@ -0,0 +1,13 @@ +package org.baeldung.java.diamond; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +public class DiamondOperatorUnitTest { + @Test + public void whenCreateCarUsingDiamondOperator_thenSuccess() { + Car myCar = new Car<>(); + assertNotNull(myCar); + } +} diff --git a/core-java/src/test/java/org/baeldung/java/diamond/Diesel.java b/core-java/src/test/java/org/baeldung/java/diamond/Diesel.java new file mode 100644 index 0000000000..dc4256cdae --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/diamond/Diesel.java @@ -0,0 +1,10 @@ +package org.baeldung.java.diamond; + +public class Diesel implements Engine { + + @Override + public void start() { + System.out.println("Started Diesel..."); + } + +} diff --git a/core-java/src/test/java/org/baeldung/java/diamond/Engine.java b/core-java/src/test/java/org/baeldung/java/diamond/Engine.java new file mode 100644 index 0000000000..c18a8f64b5 --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/diamond/Engine.java @@ -0,0 +1,6 @@ +package org.baeldung.java.diamond; + +public interface Engine { + + void start(); +} diff --git a/core-java/src/test/java/org/baeldung/java/diamond/Vehicle.java b/core-java/src/test/java/org/baeldung/java/diamond/Vehicle.java new file mode 100644 index 0000000000..f61cf59620 --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/diamond/Vehicle.java @@ -0,0 +1,5 @@ +package org.baeldung.java.diamond; + +public interface Vehicle { + +} diff --git a/core-java/src/test/java/org/baeldung/java/rawtypes/RawTypesTest.java b/core-java/src/test/java/org/baeldung/java/rawtypes/RawTypesTest.java new file mode 100644 index 0000000000..2b36786abf --- /dev/null +++ b/core-java/src/test/java/org/baeldung/java/rawtypes/RawTypesTest.java @@ -0,0 +1,17 @@ +package org.baeldung.java.rawtypes; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +public class RawTypesTest { + @Test + public void shouldCreateListUsingRawTypes() { + @SuppressWarnings("rawtypes") + List myList = new ArrayList(); + myList.add(new Object()); + myList.add("2"); + myList.add(new Integer(1)); + } +} diff --git a/core-java/src/test/resources/original.txt b/core-java/src/test/resources/original.txt new file mode 100644 index 0000000000..cf8c89d389 --- /dev/null +++ b/core-java/src/test/resources/original.txt @@ -0,0 +1,2 @@ +#Copy a File with Java (www.Baeldung.com) +Copying Files with Java is Fun! \ No newline at end of file diff --git a/kotlin/README.md b/core-kotlin/README.md similarity index 82% rename from kotlin/README.md rename to core-kotlin/README.md index 91933e94dc..4b5f921f7b 100644 --- a/kotlin/README.md +++ b/core-kotlin/README.md @@ -13,4 +13,8 @@ - [Overview of Kotlin Collections API](http://www.baeldung.com/kotlin-collections-api) - [Converting a List to Map in Kotlin](http://www.baeldung.com/kotlin-list-to-map) - [Data Classes in Kotlin](http://www.baeldung.com/kotlin-data-classes) +- [Delegated Properties in Kotlin](http://www.baeldung.com/kotlin-delegated-properties) +- [Sealed Classes in Kotlin](http://www.baeldung.com/kotlin-sealed-classes) +- [JUnit 5 for Kotlin Developers](http://www.baeldung.com/junit-5-kotlin) + diff --git a/kotlin/pom.xml b/core-kotlin/pom.xml similarity index 68% rename from kotlin/pom.xml rename to core-kotlin/pom.xml index e88013ab69..e795d1e042 100644 --- a/kotlin/pom.xml +++ b/core-kotlin/pom.xml @@ -3,8 +3,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - kotlin + core-kotlin 1.0-SNAPSHOT + jar com.baeldung @@ -20,6 +21,24 @@ + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + junit + junit + ${junit4.version} + test + org.jetbrains.kotlin kotlin-stdlib @@ -116,16 +135,51 @@ + + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + maven-failsafe-plugin + 2.19.1 + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + + + + + junit5 + + integration-test + verify + + + + **/*Test5.java + + + + + + UTF-8 1.1.2 1.1.2 1.1.2 1.1.2 0.15 1.5.0 + + 5.0.0 + 1.0.0 + 4.12.0 + 4.12 - \ No newline at end of file + diff --git a/kotlin/src/main/java/com/baeldung/dataclass/Movie.java b/core-kotlin/src/main/java/com/baeldung/dataclass/Movie.java similarity index 100% rename from kotlin/src/main/java/com/baeldung/dataclass/Movie.java rename to core-kotlin/src/main/java/com/baeldung/dataclass/Movie.java diff --git a/kotlin/src/main/java/com/baeldung/java/ArrayExample.java b/core-kotlin/src/main/java/com/baeldung/java/ArrayExample.java similarity index 100% rename from kotlin/src/main/java/com/baeldung/java/ArrayExample.java rename to core-kotlin/src/main/java/com/baeldung/java/ArrayExample.java diff --git a/kotlin/src/main/java/com/baeldung/java/Customer.java b/core-kotlin/src/main/java/com/baeldung/java/Customer.java similarity index 100% rename from kotlin/src/main/java/com/baeldung/java/Customer.java rename to core-kotlin/src/main/java/com/baeldung/java/Customer.java diff --git a/kotlin/src/main/java/com/baeldung/java/StringUtils.java b/core-kotlin/src/main/java/com/baeldung/java/StringUtils.java similarity index 100% rename from kotlin/src/main/java/com/baeldung/java/StringUtils.java rename to core-kotlin/src/main/java/com/baeldung/java/StringUtils.java diff --git a/kotlin/src/main/java/com/baeldung/lazy/ClassWithHeavyInitialization.java b/core-kotlin/src/main/java/com/baeldung/lazy/ClassWithHeavyInitialization.java similarity index 100% rename from kotlin/src/main/java/com/baeldung/lazy/ClassWithHeavyInitialization.java rename to core-kotlin/src/main/java/com/baeldung/lazy/ClassWithHeavyInitialization.java diff --git a/kotlin/src/main/kotlin/com/baeldung/dataclass/Movie.kt b/core-kotlin/src/main/kotlin/com/baeldung/dataclass/Movie.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/dataclass/Movie.kt rename to core-kotlin/src/main/kotlin/com/baeldung/dataclass/Movie.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/dataclass/Sandbox.kt b/core-kotlin/src/main/kotlin/com/baeldung/dataclass/Sandbox.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/dataclass/Sandbox.kt rename to core-kotlin/src/main/kotlin/com/baeldung/dataclass/Sandbox.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseDuration.kt b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseDuration.kt new file mode 100644 index 0000000000..40fb161c08 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseDuration.kt @@ -0,0 +1,15 @@ +package com.baeldung.datetime + +import java.time.Duration +import java.time.LocalTime + +class UseDuration { + + fun modifyDates(localTime: LocalTime, duration: Duration): LocalTime { + return localTime.plus(duration) + } + + fun getDifferenceBetweenDates(localTime1: LocalTime, localTime2: LocalTime): Duration { + return Duration.between(localTime1, localTime2) + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseLocalDate.kt b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseLocalDate.kt new file mode 100644 index 0000000000..250c071bbe --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseLocalDate.kt @@ -0,0 +1,42 @@ +package com.baeldung.datetime + +import java.time.DayOfWeek +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.temporal.ChronoUnit +import java.time.temporal.TemporalAdjusters + +class UseLocalDate { + + fun getLocalDateUsingFactoryOfMethod(year: Int, month: Int, dayOfMonth: Int): LocalDate { + return LocalDate.of(year, month, dayOfMonth) + } + + fun getLocalDateUsingParseMethod(representation: String): LocalDate { + return LocalDate.parse(representation) + } + + fun getLocalDateFromClock(): LocalDate { + return LocalDate.now() + } + + fun getNextDay(localDate: LocalDate): LocalDate { + return localDate.plusDays(1) + } + + fun getPreviousDay(localDate: LocalDate): LocalDate { + return localDate.minus(1, ChronoUnit.DAYS) + } + + fun getDayOfWeek(localDate: LocalDate): DayOfWeek { + return localDate.dayOfWeek + } + + fun getFirstDayOfMonth(): LocalDate { + return LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()) + } + + fun getStartOfDay(localDate: LocalDate): LocalDateTime { + return localDate.atStartOfDay() + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseLocalDateTime.kt b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseLocalDateTime.kt new file mode 100644 index 0000000000..ab7bbfcee1 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseLocalDateTime.kt @@ -0,0 +1,10 @@ +package com.baeldung.datetime + +import java.time.LocalDateTime + +class UseLocalDateTime { + + fun getLocalDateTimeUsingParseMethod(representation: String): LocalDateTime { + return LocalDateTime.parse(representation) + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseLocalTime.kt b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseLocalTime.kt new file mode 100644 index 0000000000..152515621f --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseLocalTime.kt @@ -0,0 +1,32 @@ +package com.baeldung.datetime + +import java.time.LocalDateTime +import java.time.LocalTime +import java.time.temporal.ChronoUnit + +class UseLocalTime { + + fun getLocalTimeUsingFactoryOfMethod(hour: Int, min: Int, seconds: Int): LocalTime { + return LocalTime.of(hour, min, seconds) + } + + fun getLocalTimeUsingParseMethod(timeRepresentation: String): LocalTime { + return LocalTime.parse(timeRepresentation) + } + + fun getLocalTimeFromClock(): LocalTime { + return LocalTime.now() + } + + fun addAnHour(localTime: LocalTime): LocalTime { + return localTime.plus(1, ChronoUnit.HOURS) + } + + fun getHourFromLocalTime(localTime: LocalTime): Int { + return localTime.hour + } + + fun getLocalTimeWithMinuteSetToValue(localTime: LocalTime, minute: Int): LocalTime { + return localTime.withMinute(minute) + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/datetime/UsePeriod.kt b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UsePeriod.kt new file mode 100644 index 0000000000..df66a3d546 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UsePeriod.kt @@ -0,0 +1,15 @@ +package com.baeldung.datetime + +import java.time.LocalDate +import java.time.Period + +class UsePeriod { + + fun modifyDates(localDate: LocalDate, period: Period): LocalDate { + return localDate.plus(period) + } + + fun getDifferenceBetweenDates(localDate1: LocalDate, localDate2: LocalDate): Period { + return Period.between(localDate1, localDate2) + } +} \ No newline at end of file diff --git a/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseZonedDateTime.kt b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseZonedDateTime.kt new file mode 100644 index 0000000000..fd1838bd2d --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/datetime/UseZonedDateTime.kt @@ -0,0 +1,12 @@ +package com.baeldung.datetime + +import java.time.LocalDateTime +import java.time.ZoneId +import java.time.ZonedDateTime + +class UseZonedDateTime { + + fun getZonedDateTime(localDateTime: LocalDateTime, zoneId: ZoneId): ZonedDateTime { + return ZonedDateTime.of(localDateTime, zoneId) + } +} \ No newline at end of file diff --git a/kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Person.kt b/core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Person.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Person.kt rename to core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Person.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Result.kt b/core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Result.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Result.kt rename to core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Result.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Sandbox.kt b/core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Sandbox.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Sandbox.kt rename to core-kotlin/src/main/kotlin/com/baeldung/destructuringdeclarations/Sandbox.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/Example1.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/Example1.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/Example1.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/Example1.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/Item.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/Item.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/Item.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/Item.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/ItemService.kt diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/JvmSample.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/JvmSample.kt new file mode 100644 index 0000000000..610d5282b2 --- /dev/null +++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/JvmSample.kt @@ -0,0 +1,12 @@ +package com.baeldung.kotlin + +class JvmSample(text:String) { + @JvmField + val sampleText:String = text +} + +class CompanionSample { + companion object { + @JvmField val MAX_LIMIT = 20 + } +} \ No newline at end of file diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/ListExtension.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/ListExtension.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/ListExtension.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/ListExtension.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/MathematicsOperations.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/Sealed.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/User.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/User.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/User.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/User.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/WhenBlockTypes.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/WhenBlockTypes.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/WhenBlockTypes.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/WhenBlockTypes.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/Database.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/Database.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/Database.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/Database.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegate.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegate.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegate.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegate.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/User.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/User.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/User.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/delegates/User.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/BookService.kt diff --git a/kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt similarity index 100% rename from kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt rename to core-kotlin/src/main/kotlin/com/baeldung/kotlin/mockito/LendBookManager.kt diff --git a/kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java b/core-kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java similarity index 100% rename from kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java rename to core-kotlin/src/test/java/com/baeldung/kotlin/JavaCallToKotlinUnitTest.java diff --git a/kotlin/src/test/java/com/baeldung/kotlin/LazyJavaUnitTest.java b/core-kotlin/src/test/java/com/baeldung/kotlin/LazyJavaUnitTest.java similarity index 100% rename from kotlin/src/test/java/com/baeldung/kotlin/LazyJavaUnitTest.java rename to core-kotlin/src/test/java/com/baeldung/kotlin/LazyJavaUnitTest.java diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/ArrayTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ArrayTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/ArrayTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/ArrayTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/CollectionsTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CollectionsTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/CollectionsTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/CollectionsTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/CustomerTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CustomerTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/CustomerTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/CustomerTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/EqualityTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/EqualityTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/EqualityTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/EqualityTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ExtensionMethods.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ExtensionMethods.kt new file mode 100644 index 0000000000..09ce898860 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ExtensionMethods.kt @@ -0,0 +1,51 @@ +package com.baeldung.kotlin + +import org.junit.Assert +import org.junit.Test + +class ExtensionMethods { + @Test + fun simpleExtensionMethod() { + fun String.escapeForXml() : String { + return this + .replace("&", "&") + .replace("<", "<") + .replace(">", ">") + } + + Assert.assertEquals("Nothing", "Nothing".escapeForXml()) + Assert.assertEquals("<Tag>", "".escapeForXml()) + Assert.assertEquals("a&b", "a&b".escapeForXml()) + } + + @Test + fun genericExtensionMethod() { + fun T.concatAsString(b: T) : String { + return this.toString() + b.toString() + } + + Assert.assertEquals("12", "1".concatAsString("2")) + Assert.assertEquals("12", 1.concatAsString(2)) + // This doesn't compile + // Assert.assertEquals("12", 1.concatAsString(2.0)) + } + + @Test + fun infixExtensionMethod() { + infix fun Number.toPowerOf(exponent: Number): Double { + return Math.pow(this.toDouble(), exponent.toDouble()) + } + + Assert.assertEquals(9.0, 3 toPowerOf 2, 0.1) + Assert.assertEquals(3.0, 9 toPowerOf 0.5, 0.1) + } + + @Test + fun operatorExtensionMethod() { + operator fun List.times(by: Int): List { + return this.map { it * by } + } + + Assert.assertEquals(listOf(2, 4, 6), listOf(1, 2, 3) * 2) + } +} diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/GenericsTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/GenericsTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/GenericsTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/GenericsTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/ItemServiceTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ItemServiceTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/ItemServiceTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/ItemServiceTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/JvmSampleTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/JvmSampleTest.kt new file mode 100644 index 0000000000..abe6edec92 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/JvmSampleTest.kt @@ -0,0 +1,26 @@ +package com.baeldung.kotlin + +import org.junit.Before +import org.junit.Test +import kotlin.test.assertTrue + +class JvmSampleTest { + + var sample = "" + + @Before + fun setUp() { + sample = JvmSample("Hello!").sampleText + } + + @Test + fun givenField_whenCheckValue_thenMatchesValue() { + assertTrue(sample == "Hello!") + } + + @Test + fun givenStaticVariable_whenCheckValue_thenMatchesValue() { + // Sample when is treated as a static variable + assertTrue(CompanionSample.MAX_LIMIT == 20) + } +} \ No newline at end of file diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinJavaInteroperabilityTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinJavaInteroperabilityTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinJavaInteroperabilityTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/KotlinJavaInteroperabilityTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/LambdaTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/LazyUnitTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/ListExtensionTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ListExtensionTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/ListExtensionTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/ListExtensionTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/ListToMapTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ListToMapTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/ListToMapTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/ListToMapTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/NullSafetyTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/NullSafetyTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/NullSafetyTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/NullSafetyTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/SealedTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/WhenBlockUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/WhenBlockUnitTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/WhenBlockUnitTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/WhenBlockUnitTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseLocalDateTimeUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseLocalDateTimeUnitTest.kt new file mode 100644 index 0000000000..8f9f8374ed --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseLocalDateTimeUnitTest.kt @@ -0,0 +1,23 @@ +package com.baeldung.kotlin.datetime + +import com.baeldung.datetime.UseLocalDateTime +import java.time.LocalDate +import java.time.LocalTime +import java.time.Month + +import org.junit.Test + +import org.junit.Assert.assertEquals + +class UseLocalDateTimeUnitTest { + + var useLocalDateTime = UseLocalDateTime() + + @Test + fun givenString_whenUsingParse_thenLocalDateTime() { + assertEquals(LocalDate.of(2016, Month.MAY, 10), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30") + .toLocalDate()) + assertEquals(LocalTime.of(6, 30), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30") + .toLocalTime()) + } +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseLocalDateUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseLocalDateUnitTest.kt new file mode 100644 index 0000000000..ac42e91c6c --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseLocalDateUnitTest.kt @@ -0,0 +1,59 @@ +package com.baeldung.kotlin.datetime + +import com.baeldung.datetime.UseLocalDate +import org.junit.Assert +import org.junit.Test +import java.time.DayOfWeek +import java.time.LocalDate +import java.time.LocalDateTime + +class UseLocalDateUnitTest { + + var useLocalDate = UseLocalDate() + + @Test + fun givenValues_whenUsingFactoryOf_thenLocalDate() { + Assert.assertEquals("2016-05-10", useLocalDate.getLocalDateUsingFactoryOfMethod(2016, 5, 10) + .toString()) + } + + @Test + fun givenString_whenUsingParse_thenLocalDate() { + Assert.assertEquals("2016-05-10", useLocalDate.getLocalDateUsingParseMethod("2016-05-10") + .toString()) + } + + @Test + fun whenUsingClock_thenLocalDate() { + Assert.assertEquals(LocalDate.now(), useLocalDate.getLocalDateFromClock()) + } + + @Test + fun givenDate_whenUsingPlus_thenNextDay() { + Assert.assertEquals(LocalDate.now() + .plusDays(1), useLocalDate.getNextDay(LocalDate.now())) + } + + @Test + fun givenDate_whenUsingMinus_thenPreviousDay() { + Assert.assertEquals(LocalDate.now() + .minusDays(1), useLocalDate.getPreviousDay(LocalDate.now())) + } + + @Test + fun givenToday_whenUsingGetDayOfWeek_thenDayOfWeek() { + Assert.assertEquals(DayOfWeek.SUNDAY, useLocalDate.getDayOfWeek(LocalDate.parse("2016-05-22"))) + } + + @Test + fun givenToday_whenUsingWithTemporalAdjuster_thenFirstDayOfMonth() { + Assert.assertEquals(1, useLocalDate.getFirstDayOfMonth() + .dayOfMonth.toLong()) + } + + @Test + fun givenLocalDate_whenUsingAtStartOfDay_thenReturnMidnight() { + Assert.assertEquals(LocalDateTime.parse("2016-05-22T00:00:00"), useLocalDate.getStartOfDay(LocalDate.parse("2016-05-22"))) + } + +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseLocalTimeUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseLocalTimeUnitTest.kt new file mode 100644 index 0000000000..83fc57f850 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseLocalTimeUnitTest.kt @@ -0,0 +1,37 @@ +package com.baeldung.kotlin.datetime + +import com.baeldung.datetime.UseLocalTime +import java.time.LocalTime + +import org.junit.Assert +import org.junit.Test + +class UseLocalTimeUnitTest { + + internal var useLocalTime = UseLocalTime() + + @Test + fun givenValues_whenUsingFactoryOf_thenLocalTime() { + Assert.assertEquals("07:07:07", useLocalTime.getLocalTimeUsingFactoryOfMethod(7, 7, 7).toString()) + } + + @Test + fun givenString_whenUsingParse_thenLocalTime() { + Assert.assertEquals("06:30", useLocalTime.getLocalTimeUsingParseMethod("06:30").toString()) + } + + @Test + fun givenTime_whenAddHour_thenLocalTime() { + Assert.assertEquals("07:30", useLocalTime.addAnHour(LocalTime.of(6, 30)).toString()) + } + + @Test + fun getHourFromLocalTime() { + Assert.assertEquals(1, useLocalTime.getHourFromLocalTime(LocalTime.of(1, 1)).toLong()) + } + + @Test + fun getLocalTimeWithMinuteSetToValue() { + Assert.assertEquals(LocalTime.of(10, 20), useLocalTime.getLocalTimeWithMinuteSetToValue(LocalTime.of(10, 10), 20)) + } +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UsePeriodUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UsePeriodUnitTest.kt new file mode 100644 index 0000000000..48be72feb0 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UsePeriodUnitTest.kt @@ -0,0 +1,28 @@ +package com.baeldung.kotlin.datetime + +import com.baeldung.datetime.UsePeriod +import java.time.LocalDate +import java.time.Period + +import org.junit.Assert +import org.junit.Test + +class UsePeriodUnitTest { + + var usingPeriod = UsePeriod() + + @Test + fun givenPeriodAndLocalDate_thenCalculateModifiedDate() { + val period = Period.ofDays(1) + val localDate = LocalDate.parse("2007-05-10") + Assert.assertEquals(localDate.plusDays(1), usingPeriod.modifyDates(localDate, period)) + } + + @Test + fun givenDates_thenGetPeriod() { + val localDate1 = LocalDate.parse("2007-05-10") + val localDate2 = LocalDate.parse("2007-05-15") + + Assert.assertEquals(Period.ofDays(5), usingPeriod.getDifferenceBetweenDates(localDate1, localDate2)) + } +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseZonedDateTimeUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseZonedDateTimeUnitTest.kt new file mode 100644 index 0000000000..a9d7d973ef --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/datetime/UseZonedDateTimeUnitTest.kt @@ -0,0 +1,19 @@ +package com.baeldung.kotlin.datetime + +import com.baeldung.datetime.UseZonedDateTime +import org.junit.Assert +import org.junit.Test +import java.time.LocalDateTime +import java.time.ZoneId + +class UseZonedDateTimeUnitTest { + + internal var zonedDateTime = UseZonedDateTime() + + @Test + fun givenZoneId_thenZonedDateTime() { + val zoneId = ZoneId.of("Europe/Paris") + val zonedDatetime = zonedDateTime.getZonedDateTime(LocalDateTime.parse("2016-05-20T06:30"), zoneId) + Assert.assertEquals(zoneId, ZoneId.from(zonedDatetime)) + } +} \ No newline at end of file diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegatesTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegatesTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegatesTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/delegates/DatabaseDelegatesTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/Calculator.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/Calculator.kt new file mode 100644 index 0000000000..1b61c05887 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/Calculator.kt @@ -0,0 +1,17 @@ +package com.baeldung.kotlin.junit5 + +class Calculator { + fun add(a: Int, b: Int) = a + b + + fun divide(a: Int, b: Int) = if (b == 0) { + throw DivideByZeroException(a) + } else { + a / b + } + + fun square(a: Int) = a * a + + fun squareRoot(a: Int) = Math.sqrt(a.toDouble()) + + fun log(base: Int, value: Int) = Math.log(value.toDouble()) / Math.log(base.toDouble()) +} diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/CalculatorTest5.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/CalculatorTest5.kt new file mode 100644 index 0000000000..40cd9adc99 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/CalculatorTest5.kt @@ -0,0 +1,82 @@ +package com.baeldung.kotlin.junit5 + +import org.junit.jupiter.api.* +import org.junit.jupiter.api.function.Executable + +class CalculatorTest5 { + private val calculator = Calculator() + + @Test + fun whenAdding1and3_thenAnswerIs4() { + Assertions.assertEquals(4, calculator.add(1, 3)) + } + + @Test + fun whenDividingBy0_thenErrorOccurs() { + val exception = Assertions.assertThrows(DivideByZeroException::class.java) { + calculator.divide(5, 0) + } + + Assertions.assertEquals(5, exception.numerator) + } + + @Test + fun whenSquaringNumbers_thenCorrectAnswerGiven() { + Assertions.assertAll( + Executable { Assertions.assertEquals(1, calculator.square(1)) }, + Executable { Assertions.assertEquals(4, calculator.square(2)) }, + Executable { Assertions.assertEquals(9, calculator.square(3)) } + ) + } + + @TestFactory + fun testSquaresFactory() = listOf( + DynamicTest.dynamicTest("when I calculate 1^2 then I get 1") { Assertions.assertEquals(1,calculator.square(1))}, + DynamicTest.dynamicTest("when I calculate 2^2 then I get 4") { Assertions.assertEquals(4,calculator.square(2))}, + DynamicTest.dynamicTest("when I calculate 3^2 then I get 9") { Assertions.assertEquals(9,calculator.square(3))} + ) + + @TestFactory + fun testSquaresFactory2() = listOf( + 1 to 1, + 2 to 4, + 3 to 9, + 4 to 16, + 5 to 25) + .map { (input, expected) -> + DynamicTest.dynamicTest("when I calculate $input^2 then I get $expected") { + Assertions.assertEquals(expected, calculator.square(input)) + } + } + + private val squaresTestData = listOf( + 1 to 1, + 2 to 4, + 3 to 9, + 4 to 16, + 5 to 25) + + @TestFactory + fun testSquaresFactory3() = squaresTestData + .map { (input, expected) -> + DynamicTest.dynamicTest("when I calculate $input^2 then I get $expected") { + Assertions.assertEquals(expected, calculator.square(input)) + } + } + @TestFactory + fun testSquareRootsFactory3() = squaresTestData + .map { (expected, input) -> + DynamicTest.dynamicTest("I calculate the square root of $input then I get $expected") { + Assertions.assertEquals(expected.toDouble(), calculator.squareRoot(input)) + } + } + + @Tags( + Tag("slow"), + Tag("logarithms") + ) + @Test + fun whenIcalculateLog2Of8_thenIget3() { + Assertions.assertEquals(3.0, calculator.log(2, 8)) + } +} diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/DivideByZeroException.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/DivideByZeroException.kt new file mode 100644 index 0000000000..60bc4e2944 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/DivideByZeroException.kt @@ -0,0 +1,3 @@ +package com.baeldung.kotlin.junit5 + +class DivideByZeroException(val numerator: Int) : Exception() diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/SimpleTest5.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/SimpleTest5.kt new file mode 100644 index 0000000000..70d3fb90bf --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/junit5/SimpleTest5.kt @@ -0,0 +1,21 @@ +package com.baeldung.kotlin.junit5 + +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + +class SimpleTest5 { + @Test + fun whenEmptyList_thenListIsEmpty() { + val list = listOf() + Assertions.assertTrue(list::isEmpty) + } + + @Test + @Disabled + fun when3equals4_thenTestFails() { + Assertions.assertEquals(3, 4) { + "Three does not equal four" + } + } +} diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTest.kt diff --git a/kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt similarity index 100% rename from kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/mockito/LendBookManagerTestMockitoKotlin.kt diff --git a/couchbase/.gitignore b/couchbase/.gitignore new file mode 100644 index 0000000000..f6867e01bd --- /dev/null +++ b/couchbase/.gitignore @@ -0,0 +1,6 @@ +# Created by .ignore support plugin (hsz.mobi) + +# IntelliJ project files +.idea +*.iml +/target/ diff --git a/couchbase-sdk/README.md b/couchbase/README.md similarity index 100% rename from couchbase-sdk/README.md rename to couchbase/README.md diff --git a/couchbase-sdk/mvnw b/couchbase/mvnw old mode 100755 new mode 100644 similarity index 100% rename from couchbase-sdk/mvnw rename to couchbase/mvnw diff --git a/couchbase-sdk/mvnw.cmd b/couchbase/mvnw.cmd similarity index 100% rename from couchbase-sdk/mvnw.cmd rename to couchbase/mvnw.cmd diff --git a/couchbase-sdk/pom.xml b/couchbase/pom.xml similarity index 88% rename from couchbase-sdk/pom.xml rename to couchbase/pom.xml index fd9e1b08f6..c79ce853d0 100644 --- a/couchbase-sdk/pom.xml +++ b/couchbase/pom.xml @@ -6,7 +6,7 @@ couchbase-sdk 0.1-SNAPSHOT jar - couchbase-sdk + couchbase Couchbase SDK Tutorials @@ -23,6 +23,12 @@ ${couchbase.client.version} + + com.fasterxml.jackson.core + jackson-databind + ${jackson-version} + + org.springframework @@ -67,9 +73,10 @@ 1.8 UTF-8 - 2.4.0 + 2.5.0 4.3.5.RELEASE 3.5 + 2.9.1 diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java b/couchbase/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/CouchbaseEntity.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/Person.java b/couchbase/src/main/java/com/baeldung/couchbase/async/person/Person.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/Person.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/person/Person.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonCrudService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java b/couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/person/PersonDocumentConverter.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/person/RegistrationService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractBucketService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/service/AbstractCrudService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/BucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/BucketService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/BucketService.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/service/BucketService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/service/ClusterServiceImpl.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/CrudService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/CrudService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/CrudService.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/service/CrudService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/service/JsonDocumentConverter.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java rename to couchbase/src/main/java/com/baeldung/couchbase/async/service/TutorialBucketService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java b/couchbase/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java rename to couchbase/src/main/java/com/baeldung/couchbase/intro/CodeSnippets.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java rename to couchbase/src/main/java/com/baeldung/couchbase/mapreduce/CouchbaseKeyGenerator.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java rename to couchbase/src/main/java/com/baeldung/couchbase/mapreduce/DuplicateKeyException.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java rename to couchbase/src/main/java/com/baeldung/couchbase/mapreduce/RandomUUIDGenerator.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java rename to couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGrade.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java rename to couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeKeyGenerator.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java rename to couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeQueryBuilder.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java b/couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java rename to couchbase/src/main/java/com/baeldung/couchbase/mapreduce/StudentGradeService.java diff --git a/couchbase/src/main/java/com/baeldung/couchbase/n1ql/BucketFactory.java b/couchbase/src/main/java/com/baeldung/couchbase/n1ql/BucketFactory.java new file mode 100644 index 0000000000..98fbe17e60 --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/n1ql/BucketFactory.java @@ -0,0 +1,26 @@ +package com.baeldung.couchbase.n1ql; + +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class BucketFactory { + + @Autowired + private Cluster cluster; + + private Bucket travelSampleBucket; + private Bucket testBucket; + + public Bucket getTravelSampleBucket() { + return (travelSampleBucket != null) ? + travelSampleBucket : cluster.openBucket("travel-sample"); + } + + public Bucket getTestBucket() { + return (testBucket != null) ? + testBucket : cluster.openBucket("test"); + } +} diff --git a/couchbase/src/main/java/com/baeldung/couchbase/n1ql/CodeSnippets.java b/couchbase/src/main/java/com/baeldung/couchbase/n1ql/CodeSnippets.java new file mode 100644 index 0000000000..45067911cb --- /dev/null +++ b/couchbase/src/main/java/com/baeldung/couchbase/n1ql/CodeSnippets.java @@ -0,0 +1,34 @@ +package com.baeldung.couchbase.n1ql; + +import com.couchbase.client.java.query.N1qlQueryResult; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +public class CodeSnippets { + + private static ObjectMapper objectMapper = new ObjectMapper(); + + private static final Logger logger = Logger.getLogger(CodeSnippets.class.getName()); + + public static List extractJsonResult(N1qlQueryResult result) { + return result.allRows().stream() + .map(row -> { + try { + return objectMapper.readTree(row.value().toString()); + }catch (IOException e) { + logger.log(Level.WARNING, e.getLocalizedMessage()); + return null; + } + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + +} diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/Person.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/Person.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/Person.java rename to couchbase/src/main/java/com/baeldung/couchbase/spring/person/Person.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java rename to couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonCrudService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java rename to couchbase/src/main/java/com/baeldung/couchbase/spring/person/PersonDocumentConverter.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/RegistrationService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/person/RegistrationService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/person/RegistrationService.java rename to couchbase/src/main/java/com/baeldung/couchbase/spring/person/RegistrationService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/BucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/BucketService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/BucketService.java rename to couchbase/src/main/java/com/baeldung/couchbase/spring/service/BucketService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/ClusterService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/ClusterService.java rename to couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/ClusterServiceImpl.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterServiceImpl.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/ClusterServiceImpl.java rename to couchbase/src/main/java/com/baeldung/couchbase/spring/service/ClusterServiceImpl.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/CrudService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/CrudService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/CrudService.java rename to couchbase/src/main/java/com/baeldung/couchbase/spring/service/CrudService.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java rename to couchbase/src/main/java/com/baeldung/couchbase/spring/service/JsonDocumentConverter.java diff --git a/couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java b/couchbase/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java similarity index 100% rename from couchbase-sdk/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java rename to couchbase/src/main/java/com/baeldung/couchbase/spring/service/TutorialBucketService.java diff --git a/couchbase-sdk/src/main/resources/application.properties b/couchbase/src/main/resources/application.properties similarity index 100% rename from couchbase-sdk/src/main/resources/application.properties rename to couchbase/src/main/resources/application.properties diff --git a/couchbase-sdk/src/test/resources/logback.xml b/couchbase/src/main/resources/logback.xml similarity index 100% rename from couchbase-sdk/src/test/resources/logback.xml rename to couchbase/src/main/resources/logback.xml diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java similarity index 100% rename from couchbase-sdk/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTest.java diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java b/couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java similarity index 100% rename from couchbase-sdk/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java rename to couchbase/src/test/java/com/baeldung/couchbase/async/AsyncIntegrationTestConfig.java diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java similarity index 100% rename from couchbase-sdk/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/async/person/PersonCrudServiceIntegrationTest.java diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java similarity index 100% rename from couchbase-sdk/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/async/service/ClusterServiceIntegrationTest.java diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java similarity index 100% rename from couchbase-sdk/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/mapreduce/StudentGradeServiceIntegrationTest.java diff --git a/couchbase/src/test/java/com/baeldung/couchbase/n1ql/IntegrationTestConfig.java b/couchbase/src/test/java/com/baeldung/couchbase/n1ql/IntegrationTestConfig.java new file mode 100644 index 0000000000..ef7e31b224 --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/n1ql/IntegrationTestConfig.java @@ -0,0 +1,26 @@ +package com.baeldung.couchbase.n1ql; + +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.CouchbaseCluster; +import com.couchbase.client.java.env.CouchbaseEnvironment; +import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.TimeUnit; + +@Configuration +@ComponentScan(basePackages = { "com.baeldung.couchbase.n1ql" }) +public class IntegrationTestConfig { + + @Bean + public Cluster cluster() { + CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder() + .connectTimeout(60000) + .build(); + return CouchbaseCluster.create(env, "127.0.0.1"); + } + + +} diff --git a/couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLIntegrationTest.java new file mode 100644 index 0000000000..8112d7d222 --- /dev/null +++ b/couchbase/src/test/java/com/baeldung/couchbase/n1ql/N1QLIntegrationTest.java @@ -0,0 +1,248 @@ +package com.baeldung.couchbase.n1ql; + +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.document.JsonDocument; +import com.couchbase.client.java.document.json.JsonArray; +import com.couchbase.client.java.document.json.JsonObject; +import com.couchbase.client.java.query.N1qlQuery; +import com.couchbase.client.java.query.N1qlQueryResult; +import com.couchbase.client.java.query.N1qlQueryRow; +import com.couchbase.client.java.query.Statement; +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import rx.Observable; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static com.baeldung.couchbase.n1ql.CodeSnippets.extractJsonResult; +import static com.couchbase.client.java.query.Select.select; +import static com.couchbase.client.java.query.dsl.Expression.*; +import static org.junit.Assert.assertNotNull; + + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { IntegrationTestConfig.class }) +public class N1QLIntegrationTest { + + + @Autowired + private Cluster cluster; + + @Autowired + private BucketFactory bucketFactory; + + @Test + public void givenAutowiredCluster_whenNotNull_thenNotNull() { + assertNotNull(cluster); + } + + @Test + public void givenBucketFactory_whenGetTestBucket_thenNotNull() { + assertNotNull(bucketFactory.getTestBucket()); + } + + @Test + public void givenBucketFactory_whenGetTravelSampleBucket_thenNotNull() { + assertNotNull(bucketFactory.getTravelSampleBucket()); + } + + @Test + public void givenDocument_whenInsert_thenResult() { + Bucket bucket = bucketFactory.getTestBucket(); + JsonObject personObj = JsonObject.create() + .put("name", "John") + .put("email", "john@doe.com") + .put("interests", JsonArray.from("Java", "Nigerian Jollof")); + + String id = UUID.randomUUID().toString(); + JsonDocument doc = JsonDocument.create(id, personObj); + bucket.insert(doc); + assertNotNull(bucket.get(id)); + } + + @Test + public void whenBasicSelectQuery_thenGetQueryResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + N1qlQueryResult result + = bucket.query(N1qlQuery.simple("SELECT * FROM test")); + + result.forEach(System.out::println); + + System.out.println("result count: " + result.info().resultCount()); + System.out.println("error count: " + result.info().errorCount()); + } + + @Test + public void givenSelectStatement_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query = "SELECT name FROM `travel-sample` " + + "WHERE type = 'airport' LIMIT 100"; + N1qlQueryResult result1 = bucket.query(N1qlQuery.simple(query)); + + System.out.println("Result Count " + result1.info().resultCount()); + + N1qlQueryRow row = result1.allRows().get(0); + JsonObject rowJson = row.value(); + System.out.println("Name in First Row " + rowJson.get("name")); + + } + + @Test + public void givenSelectStatement2_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + JsonObject pVal = JsonObject.create().put("type", "airport"); + String query = "SELECT * FROM `travel-sample` " + + "WHERE type = $type LIMIT 100"; + N1qlQueryResult r2 = bucket.query(N1qlQuery.parameterized(query, pVal)); + + System.out.println(r2.allRows()); + + List list = extractJsonResult(r2); + System.out.println( + list.get(0).get("travel-sample").get("airportname").asText()); + } + + @Test + public void givenSelectDSL_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + Statement statement = select("*") + .from(i("travel-sample")) + .where(x("type").eq(s("airport"))) + .limit(100); + N1qlQueryResult r3 = bucket.query(N1qlQuery.simple(statement)); + + List list2 = extractJsonResult(r3); + System.out.println("First Airport Name: " + list2.get(0).get("travel-sample").get("airportname").asText()); + + } + + @Test + public void givenSelectStatementWithOperators_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query2 = "SELECT t.city, " + + "t.airportname || \" (\" || t.faa || \")\" AS portname_faa " + + "FROM `travel-sample` t " + + "WHERE t.type=\"airport\"" + + "AND t.country LIKE '%States'" + + "AND t.geo.lat >= 70 " + + "LIMIT 2"; + N1qlQueryResult r4 = bucket.query(N1qlQuery.simple(query2)); + List list3 = extractJsonResult(r4); + System.out.println("First Doc : " + list3.get(0)); + } + + @Test + public void givenSelectStatementWithDSL2_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + Statement st2 = select( + x("t.city, t.airportname") + .concat(s(" (")).concat(x("t.faa")).concat(s(")")).as("portname_faa")) + .from(i("travel-sample").as("t")) + .where( x("t.type").eq(s("airport")) + .and(x("t.country").like(s("%States"))) + .and(x("t.geo.lat").gte(70))) + .limit(2); + N1qlQueryResult r5 = bucket.query(N1qlQuery.simple(st2)); + List list5 = extractJsonResult(r5); + System.out.println("First Doc : " + list5.get(0)); + System.out.println("Query from Statement2: " + st2.toString()); + } + + @Test + public void givenInsertStatement_whenQuery_thenUpdate() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query = "INSERT INTO `travel-sample` (KEY, VALUE) " + + " VALUES(" + + "\"cust1293\", " + + "{\"id\":\"1293\",\"name\":\"Sample Airline\", \"type\":\"airline\"})" + + " RETURNING META().id as docid, *"; + N1qlQueryResult r1 = bucket.query(N1qlQuery.simple(query)); + r1.forEach(System.out::println); + } + + @Test + public void givenDocument_whenInsert_thenResults() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + JsonObject ob = JsonObject.create() + .put("id", "1293") + .put("name", "Sample Airline") + .put("type", "airline"); + bucket.insert(JsonDocument.create("cust1295", ob)); + } + + @Test + public void givenDocuments_whenBatchInsert_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + + List documents = IntStream.rangeClosed(0,10) + .mapToObj( i -> { + JsonObject content = JsonObject.create() + .put("id", i) + .put("type", "airline") + .put("name", "Sample Airline " + i); + return JsonDocument.create("cust_" + i, content); + }) + .collect(Collectors.toList()); + + List r5 = Observable + .from(documents) + .flatMap(doc -> bucket.async().insert(doc)) + .toList() + .last() + .toBlocking() + .single(); + + r5.forEach(System.out::println); + } + + @Test + public void givenUpdateStatement_whenQuery_thenUpdate() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query2 = "UPDATE `travel-sample` USE KEYS \"cust_1\" " + + "SET name=\"Sample Airline Updated\" RETURNING name"; + N1qlQueryResult result = bucket.query(N1qlQuery.simple(query2)); + result.forEach(System.out::println); + } + + @Test + public void givenDocument_whenUpsert_thenUpdate() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + JsonObject o2 = JsonObject.create() + .put("name", "Sample Airline Updated"); + bucket.upsert(JsonDocument.create("cust_1", o2)); + } + + @Test + public void givenUnestUpdateStatement_whenQuery_thenResult() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query3 = "UPDATE `travel-sample` USE KEYS \"cust_2\" " + + "UNSET name RETURNING *"; + N1qlQueryResult result1 = bucket.query(N1qlQuery.simple(query3)); + result1.forEach(System.out::println); + } + + @Test + public void givenDeleteStatement_whenQuery_thenDelete() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query4 = "DELETE FROM `travel-sample` USE KEYS \"cust_50\""; + N1qlQueryResult result4 = bucket.query(N1qlQuery.simple(query4)); + } + + @Test + public void givenDeleteStatement2_whenQuery_thenDelete() { + Bucket bucket = bucketFactory.getTravelSampleBucket(); + String query5 = "DELETE FROM `travel-sample` WHERE id = 0 RETURNING *"; + N1qlQueryResult result5 = bucket.query(N1qlQuery.simple(query5)); + } + + +} diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java similarity index 100% rename from couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTest.java diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java b/couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java similarity index 100% rename from couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java rename to couchbase/src/test/java/com/baeldung/couchbase/spring/IntegrationTestConfig.java diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java similarity index 100% rename from couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/spring/person/PersonCrudServiceIntegrationTest.java diff --git a/couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java b/couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java similarity index 100% rename from couchbase-sdk/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java rename to couchbase/src/test/java/com/baeldung/couchbase/spring/service/ClusterServiceIntegrationTest.java diff --git a/mockito/src/main/resources/logback.xml b/couchbase/src/test/resources/logback.xml similarity index 100% rename from mockito/src/main/resources/logback.xml rename to couchbase/src/test/resources/logback.xml diff --git a/deeplearning4j/README.md b/deeplearning4j/README.md new file mode 100644 index 0000000000..7f9c92ec73 --- /dev/null +++ b/deeplearning4j/README.md @@ -0,0 +1,5 @@ +### Sample deeplearning4j Project +This is a sample project for the [deeplearning4j](https://deeplearning4j.org) library. + +### Relevant Articles: +- [A Guide to deeplearning4j](http://www.baeldung.com/deeplearning4j) diff --git a/deeplearning4j/pom.xml b/deeplearning4j/pom.xml new file mode 100644 index 0000000000..a39fabc3d6 --- /dev/null +++ b/deeplearning4j/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + com.baeldung.deeplearning4j + deeplearning4j + jar + 1.0-SNAPSHOT + deeplearning4j + + + UTF-8 + 1.8 + 1.8 + 0.9.1 + + + + + + org.nd4j + nd4j-native-platform + ${dl4j.version} + + + + org.deeplearning4j + deeplearning4j-core + ${dl4j.version} + + + + + \ No newline at end of file diff --git a/deeplearning4j/src/main/java/com/baeldung/deeplearning4j/IrisClassifier.java b/deeplearning4j/src/main/java/com/baeldung/deeplearning4j/IrisClassifier.java new file mode 100644 index 0000000000..bf341209e1 --- /dev/null +++ b/deeplearning4j/src/main/java/com/baeldung/deeplearning4j/IrisClassifier.java @@ -0,0 +1,80 @@ +package com.baeldung.deeplearning4j; + +import org.datavec.api.records.reader.RecordReader; +import org.datavec.api.records.reader.impl.csv.CSVRecordReader; +import org.datavec.api.split.FileSplit; +import org.datavec.api.util.ClassPathResource; +import org.deeplearning4j.datasets.datavec.RecordReaderDataSetIterator; +import org.deeplearning4j.eval.Evaluation; +import org.deeplearning4j.nn.conf.MultiLayerConfiguration; +import org.deeplearning4j.nn.conf.NeuralNetConfiguration; +import org.deeplearning4j.nn.conf.layers.DenseLayer; +import org.deeplearning4j.nn.conf.layers.OutputLayer; +import org.deeplearning4j.nn.multilayer.MultiLayerNetwork; +import org.deeplearning4j.nn.weights.WeightInit; +import org.nd4j.linalg.activations.Activation; +import org.nd4j.linalg.api.ndarray.INDArray; +import org.nd4j.linalg.dataset.DataSet; +import org.nd4j.linalg.dataset.SplitTestAndTrain; +import org.nd4j.linalg.dataset.api.iterator.DataSetIterator; +import org.nd4j.linalg.dataset.api.preprocessor.DataNormalization; +import org.nd4j.linalg.dataset.api.preprocessor.NormalizerStandardize; +import org.nd4j.linalg.lossfunctions.LossFunctions; + +import java.io.IOException; + +public class IrisClassifier { + + private static final int CLASSES_COUNT = 3; + private static final int FEATURES_COUNT = 4; + + public static void main(String[] args) throws IOException, InterruptedException { + + DataSet allData; + try (RecordReader recordReader = new CSVRecordReader(0, ',')) { + recordReader.initialize(new FileSplit(new ClassPathResource("iris.txt").getFile())); + + DataSetIterator iterator = new RecordReaderDataSetIterator(recordReader, 150, FEATURES_COUNT, CLASSES_COUNT); + allData = iterator.next(); + } + + allData.shuffle(42); + + DataNormalization normalizer = new NormalizerStandardize(); + normalizer.fit(allData); + normalizer.transform(allData); + + SplitTestAndTrain testAndTrain = allData.splitTestAndTrain(0.65); + DataSet trainingData = testAndTrain.getTrain(); + DataSet testData = testAndTrain.getTest(); + + MultiLayerConfiguration configuration = new NeuralNetConfiguration.Builder() + .iterations(1000) + .activation(Activation.TANH) + .weightInit(WeightInit.XAVIER) + .learningRate(0.1) + .regularization(true).l2(0.0001) + .list() + .layer(0, new DenseLayer.Builder().nIn(FEATURES_COUNT).nOut(3) + .build()) + .layer(1, new DenseLayer.Builder().nIn(3).nOut(3) + .build()) + .layer(2, new OutputLayer.Builder(LossFunctions.LossFunction.NEGATIVELOGLIKELIHOOD) + .activation(Activation.SOFTMAX) + .nIn(3).nOut(CLASSES_COUNT).build()) + .backprop(true).pretrain(false) + .build(); + + MultiLayerNetwork model = new MultiLayerNetwork(configuration); + model.init(); + model.fit(trainingData); + + INDArray output = model.output(testData.getFeatureMatrix()); + + Evaluation eval = new Evaluation(CLASSES_COUNT); + eval.eval(testData.getLabels(), output); + System.out.println(eval.stats()); + + } + +} diff --git a/deeplearning4j/src/main/resources/iris.txt b/deeplearning4j/src/main/resources/iris.txt new file mode 100644 index 0000000000..8b4511f8be --- /dev/null +++ b/deeplearning4j/src/main/resources/iris.txt @@ -0,0 +1,150 @@ +5.1,3.5,1.4,0.2,0 +4.9,3.0,1.4,0.2,0 +4.7,3.2,1.3,0.2,0 +4.6,3.1,1.5,0.2,0 +5.0,3.6,1.4,0.2,0 +5.4,3.9,1.7,0.4,0 +4.6,3.4,1.4,0.3,0 +5.0,3.4,1.5,0.2,0 +4.4,2.9,1.4,0.2,0 +4.9,3.1,1.5,0.1,0 +5.4,3.7,1.5,0.2,0 +4.8,3.4,1.6,0.2,0 +4.8,3.0,1.4,0.1,0 +4.3,3.0,1.1,0.1,0 +5.8,4.0,1.2,0.2,0 +5.7,4.4,1.5,0.4,0 +5.4,3.9,1.3,0.4,0 +5.1,3.5,1.4,0.3,0 +5.7,3.8,1.7,0.3,0 +5.1,3.8,1.5,0.3,0 +5.4,3.4,1.7,0.2,0 +5.1,3.7,1.5,0.4,0 +4.6,3.6,1.0,0.2,0 +5.1,3.3,1.7,0.5,0 +4.8,3.4,1.9,0.2,0 +5.0,3.0,1.6,0.2,0 +5.0,3.4,1.6,0.4,0 +5.2,3.5,1.5,0.2,0 +5.2,3.4,1.4,0.2,0 +4.7,3.2,1.6,0.2,0 +4.8,3.1,1.6,0.2,0 +5.4,3.4,1.5,0.4,0 +5.2,4.1,1.5,0.1,0 +5.5,4.2,1.4,0.2,0 +4.9,3.1,1.5,0.1,0 +5.0,3.2,1.2,0.2,0 +5.5,3.5,1.3,0.2,0 +4.9,3.1,1.5,0.1,0 +4.4,3.0,1.3,0.2,0 +5.1,3.4,1.5,0.2,0 +5.0,3.5,1.3,0.3,0 +4.5,2.3,1.3,0.3,0 +4.4,3.2,1.3,0.2,0 +5.0,3.5,1.6,0.6,0 +5.1,3.8,1.9,0.4,0 +4.8,3.0,1.4,0.3,0 +5.1,3.8,1.6,0.2,0 +4.6,3.2,1.4,0.2,0 +5.3,3.7,1.5,0.2,0 +5.0,3.3,1.4,0.2,0 +7.0,3.2,4.7,1.4,1 +6.4,3.2,4.5,1.5,1 +6.9,3.1,4.9,1.5,1 +5.5,2.3,4.0,1.3,1 +6.5,2.8,4.6,1.5,1 +5.7,2.8,4.5,1.3,1 +6.3,3.3,4.7,1.6,1 +4.9,2.4,3.3,1.0,1 +6.6,2.9,4.6,1.3,1 +5.2,2.7,3.9,1.4,1 +5.0,2.0,3.5,1.0,1 +5.9,3.0,4.2,1.5,1 +6.0,2.2,4.0,1.0,1 +6.1,2.9,4.7,1.4,1 +5.6,2.9,3.6,1.3,1 +6.7,3.1,4.4,1.4,1 +5.6,3.0,4.5,1.5,1 +5.8,2.7,4.1,1.0,1 +6.2,2.2,4.5,1.5,1 +5.6,2.5,3.9,1.1,1 +5.9,3.2,4.8,1.8,1 +6.1,2.8,4.0,1.3,1 +6.3,2.5,4.9,1.5,1 +6.1,2.8,4.7,1.2,1 +6.4,2.9,4.3,1.3,1 +6.6,3.0,4.4,1.4,1 +6.8,2.8,4.8,1.4,1 +6.7,3.0,5.0,1.7,1 +6.0,2.9,4.5,1.5,1 +5.7,2.6,3.5,1.0,1 +5.5,2.4,3.8,1.1,1 +5.5,2.4,3.7,1.0,1 +5.8,2.7,3.9,1.2,1 +6.0,2.7,5.1,1.6,1 +5.4,3.0,4.5,1.5,1 +6.0,3.4,4.5,1.6,1 +6.7,3.1,4.7,1.5,1 +6.3,2.3,4.4,1.3,1 +5.6,3.0,4.1,1.3,1 +5.5,2.5,4.0,1.3,1 +5.5,2.6,4.4,1.2,1 +6.1,3.0,4.6,1.4,1 +5.8,2.6,4.0,1.2,1 +5.0,2.3,3.3,1.0,1 +5.6,2.7,4.2,1.3,1 +5.7,3.0,4.2,1.2,1 +5.7,2.9,4.2,1.3,1 +6.2,2.9,4.3,1.3,1 +5.1,2.5,3.0,1.1,1 +5.7,2.8,4.1,1.3,1 +6.3,3.3,6.0,2.5,2 +5.8,2.7,5.1,1.9,2 +7.1,3.0,5.9,2.1,2 +6.3,2.9,5.6,1.8,2 +6.5,3.0,5.8,2.2,2 +7.6,3.0,6.6,2.1,2 +4.9,2.5,4.5,1.7,2 +7.3,2.9,6.3,1.8,2 +6.7,2.5,5.8,1.8,2 +7.2,3.6,6.1,2.5,2 +6.5,3.2,5.1,2.0,2 +6.4,2.7,5.3,1.9,2 +6.8,3.0,5.5,2.1,2 +5.7,2.5,5.0,2.0,2 +5.8,2.8,5.1,2.4,2 +6.4,3.2,5.3,2.3,2 +6.5,3.0,5.5,1.8,2 +7.7,3.8,6.7,2.2,2 +7.7,2.6,6.9,2.3,2 +6.0,2.2,5.0,1.5,2 +6.9,3.2,5.7,2.3,2 +5.6,2.8,4.9,2.0,2 +7.7,2.8,6.7,2.0,2 +6.3,2.7,4.9,1.8,2 +6.7,3.3,5.7,2.1,2 +7.2,3.2,6.0,1.8,2 +6.2,2.8,4.8,1.8,2 +6.1,3.0,4.9,1.8,2 +6.4,2.8,5.6,2.1,2 +7.2,3.0,5.8,1.6,2 +7.4,2.8,6.1,1.9,2 +7.9,3.8,6.4,2.0,2 +6.4,2.8,5.6,2.2,2 +6.3,2.8,5.1,1.5,2 +6.1,2.6,5.6,1.4,2 +7.7,3.0,6.1,2.3,2 +6.3,3.4,5.6,2.4,2 +6.4,3.1,5.5,1.8,2 +6.0,3.0,4.8,1.8,2 +6.9,3.1,5.4,2.1,2 +6.7,3.1,5.6,2.4,2 +6.9,3.1,5.1,2.3,2 +5.8,2.7,5.1,1.9,2 +6.8,3.2,5.9,2.3,2 +6.7,3.3,5.7,2.5,2 +6.7,3.0,5.2,2.3,2 +6.3,2.5,5.0,1.9,2 +6.5,3.0,5.2,2.0,2 +6.2,3.4,5.4,2.3,2 +5.9,3.0,5.1,1.8,2 diff --git a/deltaspike/README.md b/deltaspike/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/deltaspike/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/drools/README.MD b/drools/README.MD index 4ece7608fc..b2259e2878 100644 --- a/drools/README.MD +++ b/drools/README.MD @@ -1,3 +1,3 @@ ### Relevant Articles: -[Introduction to Drools](http://www.baeldung.com/drools) -[Drools Using Rules from Excel Files](http://www.baeldung.com/drools-excel) +- [Introduction to Drools](http://www.baeldung.com/drools) +- [Drools Using Rules from Excel Files](http://www.baeldung.com/drools-excel) diff --git a/drools/pom.xml b/drools/pom.xml index 29231f150c..5f228802fa 100644 --- a/drools/pom.xml +++ b/drools/pom.xml @@ -1,24 +1,19 @@ - 4.0.0 - com.baeldung drools - 1.0.0-SNAPSHOT - com.baeldung parent-modules 1.0.0-SNAPSHOT - - - 4.4.6 - 7.1.0.Beta2 - 3.13 - + + 4.4.6 + 7.4.1.Final + 3.13 + @@ -68,4 +63,25 @@ - \ No newline at end of file + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + + + + diff --git a/drools/src/main/java/com/baeldung/drools/backward_chaining/BackwardChaining.java b/drools/src/main/java/com/baeldung/drools/backward_chaining/BackwardChaining.java new file mode 100644 index 0000000000..6f15ee510b --- /dev/null +++ b/drools/src/main/java/com/baeldung/drools/backward_chaining/BackwardChaining.java @@ -0,0 +1,30 @@ +package com.baeldung.drools.backward_chaining; + +import org.kie.api.runtime.KieSession; + +import com.baeldung.drools.config.DroolsBeanFactory; +import com.baeldung.drools.model.Fact; +import com.baeldung.drools.model.Result; + +public class BackwardChaining { + public static void main(String[] args) { + Result result = new BackwardChaining().backwardChaining(); + System.out.println(result.getValue()); + result.getFacts() + .stream() + .forEach(System.out::println); + } + + public Result backwardChaining() { + Result result = new Result(); + KieSession ksession = new DroolsBeanFactory().getKieSession(); + ksession.setGlobal("result", result); + ksession.insert(new Fact("Asia", "Planet Earth")); + ksession.insert(new Fact("China", "Asia")); + ksession.insert(new Fact("Great Wall of China", "China")); + + ksession.fireAllRules(); + + return result; + } +} \ No newline at end of file diff --git a/drools/src/main/java/com/baeldung/drools/config/DroolsBeanFactory.java b/drools/src/main/java/com/baeldung/drools/config/DroolsBeanFactory.java index e8841b05e2..cf5d56f246 100644 --- a/drools/src/main/java/com/baeldung/drools/config/DroolsBeanFactory.java +++ b/drools/src/main/java/com/baeldung/drools/config/DroolsBeanFactory.java @@ -3,7 +3,6 @@ package com.baeldung.drools.config; import org.drools.decisiontable.DecisionTableProviderImpl; import org.kie.api.KieServices; import org.kie.api.builder.*; -import org.kie.api.io.KieResources; import org.kie.api.io.Resource; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; @@ -22,7 +21,7 @@ public class DroolsBeanFactory { private KieFileSystem getKieFileSystem() throws IOException{ KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); - List rules=Arrays.asList("SuggestApplicant.drl","Product_rules.xls"); + List rules=Arrays.asList("BackwardChaining.drl","SuggestApplicant.drl","Product_rules.xls"); for(String rule:rules){ kieFileSystem.write(ResourceFactory.newClassPathResource(rule)); } @@ -56,9 +55,11 @@ public class DroolsBeanFactory { getKieRepository(); KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); + kieFileSystem.write(ResourceFactory.newClassPathResource("com/baeldung/drools/rules/BackwardChaining.drl")); kieFileSystem.write(ResourceFactory.newClassPathResource("com/baeldung/drools/rules/SuggestApplicant.drl")); kieFileSystem.write(ResourceFactory.newClassPathResource("com/baeldung/drools/rules/Product_rules.xls")); - + + KieBuilder kb = kieServices.newKieBuilder(kieFileSystem); kb.buildAll(); KieModule kieModule = kb.getKieModule(); diff --git a/drools/src/main/java/com/baeldung/drools/model/Fact.java b/drools/src/main/java/com/baeldung/drools/model/Fact.java new file mode 100644 index 0000000000..62b44b9d92 --- /dev/null +++ b/drools/src/main/java/com/baeldung/drools/model/Fact.java @@ -0,0 +1,69 @@ +package com.baeldung.drools.model; + +import org.kie.api.definition.type.Position; + +public class Fact { + + @Position(0) + private String element; + + @Position(1) + private String place; + + public Fact(String element, String place) { + this.element = element; + this.place = place; + } + + public String getElement() { + return element; + } + + public void setElement(String element) { + this.element = element; + } + + public String getPlace() { + return place; + } + + public void setPlace(String place) { + this.place = place; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((element == null) ? 0 : element.hashCode()); + result = prime * result + ((place == null) ? 0 : place.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Fact other = (Fact) obj; + if (element == null) { + if (other.element != null) + return false; + } else if (!element.equals(other.element)) + return false; + if (place == null) { + if (other.place != null) + return false; + } else if (!place.equals(other.place)) + return false; + return true; + } + + @Override + public String toString() { + return "Fact{" + "element='" + element + '\'' + ", place='" + place + '\'' + '}'; + } +} \ No newline at end of file diff --git a/drools/src/main/java/com/baeldung/drools/model/Result.java b/drools/src/main/java/com/baeldung/drools/model/Result.java new file mode 100644 index 0000000000..b22557832b --- /dev/null +++ b/drools/src/main/java/com/baeldung/drools/model/Result.java @@ -0,0 +1,31 @@ +package com.baeldung.drools.model; + +import java.util.ArrayList; +import java.util.List; + +public class Result { + private String value; + private List facts = new ArrayList<>(); + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public List getFacts() { + return facts; + } + + public void setFacts(List facts) { + this.facts = facts; + } + + public void addFact(String fact) { + this.facts.add(fact); + } + + +} diff --git a/drools/src/main/resources/com/baeldung/drools/rules/BackwardChaining.drl b/drools/src/main/resources/com/baeldung/drools/rules/BackwardChaining.drl new file mode 100644 index 0000000000..975be84fb4 --- /dev/null +++ b/drools/src/main/resources/com/baeldung/drools/rules/BackwardChaining.drl @@ -0,0 +1,27 @@ +package com.baeldung.drools.rules + +import com.baeldung.drools.model.Fact; + +global com.baeldung.drools.model.Result result; + +dialect "mvel" + +query belongsTo(String x, String y) + Fact(x, y;) + or + (Fact(z, y;) and belongsTo(x, z;)) +end + +rule "Great Wall of China BELONGS TO Planet Earth" +when + belongsTo("Great Wall of China", "Planet Earth";) +then + result.setValue("Decision one taken: Great Wall of China BELONGS TO Planet Earth"); +end + +rule "print all facts" +when + belongsTo(element, place;) +then + result.addFact(element + " IS ELEMENT OF " + place); +end diff --git a/drools/src/test/java/com/baeldung/drools/backward_chaining/BackwardChainingTest.java b/drools/src/test/java/com/baeldung/drools/backward_chaining/BackwardChainingTest.java new file mode 100644 index 0000000000..f49d0b82de --- /dev/null +++ b/drools/src/test/java/com/baeldung/drools/backward_chaining/BackwardChainingTest.java @@ -0,0 +1,36 @@ +package com.baeldung.drools.backward_chaining; + +import org.junit.Before; +import org.junit.Test; +import org.kie.api.runtime.KieSession; + +import com.baeldung.drools.config.DroolsBeanFactory; +import com.baeldung.drools.model.Fact; +import com.baeldung.drools.model.Result; + +import static junit.framework.TestCase.assertEquals; + +public class BackwardChainingTest { + private Result result; + private KieSession ksession; + + @Before + public void before() { + result = new Result(); + ksession = new DroolsBeanFactory().getKieSession(); + } + + @Test + public void whenWallOfChinaIsGiven_ThenItBelongsToPlanetEarth() { + + ksession.setGlobal("result", result); + ksession.insert(new Fact("Asia", "Planet Earth")); + ksession.insert(new Fact("China", "Asia")); + ksession.insert(new Fact("Great Wall of China", "China")); + + ksession.fireAllRules(); + + // Assert Decision one + assertEquals(result.getValue(), "Decision one taken: Great Wall of China BELONGS TO Planet Earth"); + } +} diff --git a/eclipse/README.md b/eclipse/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/eclipse/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/ejb/README.md b/ejb/README.md index 3b729318d4..994781b064 100644 --- a/ejb/README.md +++ b/ejb/README.md @@ -2,3 +2,4 @@ - [Guide to EJB Set-up](http://www.baeldung.com/ejb-intro) - [Java EE Session Beans](http://www.baeldung.com/ejb-session-beans) +- [Introduction to EJB JNDI Lookup on WildFly Application Server](http://www.baeldung.com/wildfly-ejb-jndi) diff --git a/ejb/wildfly/pom.xml b/ejb/wildfly/pom.xml new file mode 100644 index 0000000000..d4843f9fc9 --- /dev/null +++ b/ejb/wildfly/pom.xml @@ -0,0 +1,81 @@ + + 4.0.0 + com.baeldung.wildfly + wildfly-example + 0.0.1-SNAPSHOT + pom + + + 1.8 + 1.8 + UTF-8 + + + widlfly-web + wildfly-ear + wildfly-jpa + wildfly-ejb-interfaces + wildfly-ejb + + + + + + + + javax + javaee-api + 7.0 + provided + + + + org.wildfly.bom + wildfly-javaee7 + 10.1.0.Final + import + pom + + + + org.hibernate + hibernate-core + 5.2.3.Final + provided + + + + com.baeldung.wildfly + wildlfy-ear + 0.0.1-SNAPSHOT + ear + + + + com.baeldung.wildfly + wildlfy-web + 0.0.1-SNAPSHOT + war + + + + com.baeldung.wildfly + wildlfy-jpa + 0.0.1-SNAPSHOT + + + + com.baeldung.wildfly + wildfly-ejb + 0.0.1-SNAPSHOT + + + + com.baeldung.wildfly + wildfly-ejb-interfaces + 0.0.1-SNAPSHOT + + + + \ No newline at end of file diff --git a/ejb/wildfly/widlfly-web/pom.xml b/ejb/wildfly/widlfly-web/pom.xml new file mode 100644 index 0000000000..2e316dedd9 --- /dev/null +++ b/ejb/wildfly/widlfly-web/pom.xml @@ -0,0 +1,39 @@ + + 4.0.0 + + com.baeldung.wildfly + wildfly-example + 0.0.1-SNAPSHOT + + widlfly-web + war + + + + + javax + javaee-api + 7.0 + provided + + + + com.baeldung.wildfly + wildfly-jpa + 0.0.1-SNAPSHOT + + + + com.baeldung.wildfly + wildfly-ejb-interfaces + 0.0.1-SNAPSHOT + + + + com.baeldung.wildfly + wildfly-ejb + 0.0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java b/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java new file mode 100644 index 0000000000..57376e9c4a --- /dev/null +++ b/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java @@ -0,0 +1,41 @@ + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; + +import javax.ejb.EJB; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import model.User; +import wildfly.beans.UserBeanLocal; + +/** + * Servlet implementation class TestEJBServlet + */ +public class TestEJBServlet extends HttpServlet { + + @EJB + private UserBeanLocal userBean; + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + List users = userBean.getUsers(); + + PrintWriter out = response.getWriter(); + + out.println(""); + out.println(""); + for (User user : users) { + out.print(user.getUsername()); + out.print(" " + user.getEmail() + "
    "); + } + out.println(""); + out.println(""); + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + doGet(request, response); + } +} diff --git a/ejb/wildfly/widlfly-web/src/main/java/TestJPAServlet.java b/ejb/wildfly/widlfly-web/src/main/java/TestJPAServlet.java new file mode 100644 index 0000000000..609366c53a --- /dev/null +++ b/ejb/wildfly/widlfly-web/src/main/java/TestJPAServlet.java @@ -0,0 +1,54 @@ + +import java.io.IOException; +import java.util.List; + +import javax.annotation.Resource; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.transaction.UserTransaction; + +import model.User; + +/** + * Servlet implementation class TestJPAServlet + */ +public class TestJPAServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + @PersistenceContext(unitName = "wildfly-jpa") + EntityManager em; + + @Resource + UserTransaction tx; + + /** + * @see HttpServlet#HttpServlet() + */ + public TestJPAServlet() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + Query q = em.createNamedQuery("User.findAll"); + List users = q.getResultList(); + response.getWriter() + .append("JPA users returned: " + users.size()); + } + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // TODO Auto-generated method stub + doGet(request, response); + } + +} diff --git a/ejb/wildfly/widlfly-web/src/main/webapp/WEB-INF/web.xml b/ejb/wildfly/widlfly-web/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..5b3f664443 --- /dev/null +++ b/ejb/wildfly/widlfly-web/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,35 @@ + + + widlfly-web + + index.html + index.htm + index.jsp + default.html + default.htm + default.jsp + + + + TestJPAServlet + TestJPAServlet + TestJPAServlet + + + TestJPAServlet + /TestJPAServlet + + + + TestEJBServlet + TestEJBServlet + TestEJBServlet + + + TestEJBServlet + /TestEJBServlet + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-ear/pom.xml b/ejb/wildfly/wildfly-ear/pom.xml new file mode 100644 index 0000000000..6beb387227 --- /dev/null +++ b/ejb/wildfly/wildfly-ear/pom.xml @@ -0,0 +1,62 @@ + + 4.0.0 + + com.baeldung.wildfly + wildfly-example + 0.0.1-SNAPSHOT + + wildfly-ear + ear + + + + + com.baeldung.wildfly + widlfly-web + 0.0.1-SNAPSHOT + war + + + + com.baeldung.wildfly + wildfly-jpa + 0.0.1-SNAPSHOT + + + + com.baeldung.wildfly + wildfly-ejb + + + + com.baeldung.wildfly + wildfly-ejb-interfaces + + + + + + + maven-ear-plugin + 2.10.1 + + lib/ + 7 + + + com.baeldung.wildfly + widlfly-web + /wildfly + + + + + + org.wildfly.plugins + wildfly-maven-plugin + 1.2.0.Final + + + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-ejb-interfaces/pom.xml b/ejb/wildfly/wildfly-ejb-interfaces/pom.xml new file mode 100644 index 0000000000..e4d2eee0c6 --- /dev/null +++ b/ejb/wildfly/wildfly-ejb-interfaces/pom.xml @@ -0,0 +1,26 @@ + + 4.0.0 + + com.baeldung.wildfly + wildfly-example + 0.0.1-SNAPSHOT + + wildfly-ejb-interfaces + + + + + javax.ejb + javax.ejb-api + 3.2 + provided + + + + com.baeldung.wildfly + wildfly-jpa + 0.0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanLocal.java b/ejb/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanLocal.java new file mode 100644 index 0000000000..16930cb5b9 --- /dev/null +++ b/ejb/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanLocal.java @@ -0,0 +1,13 @@ +package wildfly.beans; + +import java.util.List; + +import javax.ejb.Local; + +import model.User; + +@Local +public interface UserBeanLocal { + + List getUsers(); +} diff --git a/ejb/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanRemote.java b/ejb/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanRemote.java new file mode 100644 index 0000000000..5b57d4283f --- /dev/null +++ b/ejb/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanRemote.java @@ -0,0 +1,13 @@ +package wildfly.beans; + +import java.util.List; + +import javax.ejb.Remote; + +import model.User; + +@Remote +public interface UserBeanRemote { + + List getUsers(); +} diff --git a/ejb/wildfly/wildfly-ejb/pom.xml b/ejb/wildfly/wildfly-ejb/pom.xml new file mode 100644 index 0000000000..9d4464dafa --- /dev/null +++ b/ejb/wildfly/wildfly-ejb/pom.xml @@ -0,0 +1,49 @@ + + 4.0.0 + + com.baeldung.wildfly + wildfly-example + 0.0.1-SNAPSHOT + + wildfly-ejb + ejb + + + + + javax.ejb + javax.ejb-api + 3.2 + provided + + + + javax + javaee-api + provided + + + + org.hibernate + hibernate-core + + + + com.baeldung.wildfly + wildfly-ejb-interfaces + + + + + + + org.apache.maven.plugins + maven-ejb-plugin + + 3.2 + + + + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-ejb/src/main/java/wildfly/beans/UserBean.java b/ejb/wildfly/wildfly-ejb/src/main/java/wildfly/beans/UserBean.java new file mode 100644 index 0000000000..07e3cbcb32 --- /dev/null +++ b/ejb/wildfly/wildfly-ejb/src/main/java/wildfly/beans/UserBean.java @@ -0,0 +1,24 @@ +package wildfly.beans; + +import java.util.List; + +import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +import model.User; + +/** + * Session Bean implementation class UserBean + */ +@Stateless +public class UserBean implements UserBeanRemote, UserBeanLocal { + @PersistenceContext(unitName = "wildfly-jpa") + private EntityManager em; + + @Override + public List getUsers() { + return em.createNamedQuery("User.findAll") + .getResultList(); + } +} diff --git a/ejb/wildfly/wildfly-jpa/pom.xml b/ejb/wildfly/wildfly-jpa/pom.xml new file mode 100644 index 0000000000..e6f8b32e17 --- /dev/null +++ b/ejb/wildfly/wildfly-jpa/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + + com.baeldung.wildfly + wildfly-example + 0.0.1-SNAPSHOT + + wildfly-jpa + + + + + + org.hibernate + hibernate-core + provided + + + \ No newline at end of file diff --git a/ejb/wildfly/wildfly-jpa/src/main/java/model/User.java b/ejb/wildfly/wildfly-jpa/src/main/java/model/User.java new file mode 100644 index 0000000000..3a3f95bf8c --- /dev/null +++ b/ejb/wildfly/wildfly-jpa/src/main/java/model/User.java @@ -0,0 +1,51 @@ +package model; + +import java.io.Serializable; +import javax.persistence.*; + +/** + * The persistent class for the users database table. + * + */ +@Entity +@Table(name = "users") +@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u") +public class User implements Serializable { + private static final long serialVersionUID = 1L; + + @Id + private String username; + + private String email; + + @Column(name = "postal_number") + private Integer postalNumber; + + public User() { + } + + public String getUsername() { + return this.username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return this.email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Integer getPostalNumber() { + return this.postalNumber; + } + + public void setPostalNumber(Integer postalNumber) { + this.postalNumber = postalNumber; + } + +} \ No newline at end of file diff --git a/ejb/wildfly/wildfly-jpa/src/main/resources/META-INF/persistence.xml b/ejb/wildfly/wildfly-jpa/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..2aa6bc2cd7 --- /dev/null +++ b/ejb/wildfly/wildfly-jpa/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,15 @@ + + + + java:/H2DS + model.User + + + + + + + + diff --git a/ejb/wildfly/wildfly-jpa/src/main/resources/data.sql b/ejb/wildfly/wildfly-jpa/src/main/resources/data.sql new file mode 100644 index 0000000000..03eafa534e --- /dev/null +++ b/ejb/wildfly/wildfly-jpa/src/main/resources/data.sql @@ -0,0 +1 @@ +INSERT INTO users (username, email, postal_number) VALUES ('user1', 'user1@baeldung.com', 1000), ('user2', 'user2@baeldung.com', 2); \ No newline at end of file diff --git a/enterprise-patterns/README.md b/enterprise-patterns/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/enterprise-patterns/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/ethereumj/.gitgnore b/ethereumj/.gitgnore new file mode 100644 index 0000000000..9cff80e071 --- /dev/null +++ b/ethereumj/.gitgnore @@ -0,0 +1,6 @@ +.idea +target +database +logs +target +*.iml \ No newline at end of file diff --git a/ethereumj/README.md b/ethereumj/README.md new file mode 100644 index 0000000000..d2e2753438 --- /dev/null +++ b/ethereumj/README.md @@ -0,0 +1,4 @@ +## EthereumJ + +### Relevant Articles: +- [Introduction to EthereumJ](http://www.baeldung.com/ethereumj) diff --git a/ethereumj/pom.xml b/ethereumj/pom.xml new file mode 100644 index 0000000000..c9f5924d7a --- /dev/null +++ b/ethereumj/pom.xml @@ -0,0 +1,110 @@ + + + 4.0.0 + com.baeldung.ethereumj + ethereumj + war + 1.0.0 + ethereumj + + + UTF-8 + 1.8 + 8.5.4 + + + + org.springframework.boot + spring-boot-starter-parent + 1.5.6.RELEASE + + + + + Ethereum + Ethereum + https://dl.bintray.com/ethereum/maven/ + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + org.springframework.boot + spring-boot-starter-test + 1.5.6.RELEASE + test + + + + + org.ethereum + ethereumj-core + 1.5.0-RELEASE + + + + + javax.servlet + jstl + + + com.fasterxml.jackson.core + jackson-databind + 2.5.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + ethereumj + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + none + + + */EthControllerTestOne.java + + + + + + + + + + \ No newline at end of file diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/ApplicationMain.java b/ethereumj/src/main/java/com/baeldung/ethereumj/ApplicationMain.java new file mode 100644 index 0000000000..4735548bd1 --- /dev/null +++ b/ethereumj/src/main/java/com/baeldung/ethereumj/ApplicationMain.java @@ -0,0 +1,16 @@ +package com.baeldung.ethereumj; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.web.support.SpringBootServletInitializer; + +@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) +@SpringBootApplication +public class ApplicationMain extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(ApplicationMain.class, args); + } +} \ No newline at end of file diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/Constants.java b/ethereumj/src/main/java/com/baeldung/ethereumj/Constants.java new file mode 100644 index 0000000000..919958be35 --- /dev/null +++ b/ethereumj/src/main/java/com/baeldung/ethereumj/Constants.java @@ -0,0 +1,9 @@ +package com.baeldung.ethereumj; + +public class Constants { + + public static final String ENDPOINT_ONE = "/api/get/bestblock/"; + public static final String ENDPOINT_TWO = "/api/get/difficulty/"; + public static final String RESPONSE_TYPE ="application/json/"; + +} diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/beans/EthBean.java b/ethereumj/src/main/java/com/baeldung/ethereumj/beans/EthBean.java new file mode 100644 index 0000000000..7680473c6e --- /dev/null +++ b/ethereumj/src/main/java/com/baeldung/ethereumj/beans/EthBean.java @@ -0,0 +1,25 @@ +package com.baeldung.ethereumj.beans; + +import com.baeldung.ethereumj.listeners.EthListener; +import org.ethereum.core.Block; +import org.ethereum.facade.Ethereum; +import org.ethereum.facade.EthereumFactory; + +import java.math.BigInteger; + +public class EthBean { + private Ethereum ethereum; + + public void start() { + this.ethereum = EthereumFactory.createEthereum(); + this.ethereum.addListener(new EthListener(ethereum)); + } + + public Block getBestBlock() { + return this.ethereum.getBlockchain().getBestBlock(); + } + + public BigInteger getTotalDifficulty() { + return this.ethereum.getBlockchain().getTotalDifficulty(); + } +} \ No newline at end of file diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/config/EthConfig.java b/ethereumj/src/main/java/com/baeldung/ethereumj/config/EthConfig.java new file mode 100644 index 0000000000..8180cc3ce2 --- /dev/null +++ b/ethereumj/src/main/java/com/baeldung/ethereumj/config/EthConfig.java @@ -0,0 +1,18 @@ +package com.baeldung.ethereumj.config; + +import com.baeldung.ethereumj.beans.EthBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.Executors; + +@Configuration +public class EthConfig { + + @Bean + EthBean ethBeanConfig() throws Exception { + EthBean eBean = new EthBean(); + Executors.newSingleThreadExecutor().submit(eBean::start); + return eBean; + } +} \ No newline at end of file diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/controllers/EthController.java b/ethereumj/src/main/java/com/baeldung/ethereumj/controllers/EthController.java new file mode 100644 index 0000000000..8240d60e30 --- /dev/null +++ b/ethereumj/src/main/java/com/baeldung/ethereumj/controllers/EthController.java @@ -0,0 +1,44 @@ +package com.baeldung.ethereumj.controllers; + +import com.baeldung.ethereumj.Constants; +import com.baeldung.ethereumj.beans.EthBean; +import com.baeldung.ethereumj.transfer.EthResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.PostConstruct; +import javax.servlet.ServletContext; + +@RestController +public class EthController { + + @Autowired + EthBean ethBean; + @Autowired + private ServletContext servletContext; + private Logger l = LoggerFactory.getLogger(EthController.class); + + @RequestMapping(Constants.ENDPOINT_ONE) + public EthResponse getBestBlock() { + l.debug("Request received - fetching best block."); + EthResponse r = new EthResponse(); + r.setResponse(ethBean.getBestBlock().toString()); + return r; + } + + @RequestMapping(Constants.ENDPOINT_TWO) + public EthResponse getTotalDifficulty() { + l.debug("Request received - calculating total difficulty."); + EthResponse r = new EthResponse(); + r.setResponse(ethBean.getTotalDifficulty().toString()); + return r; + } + + @PostConstruct + public void showIt() { + l.debug(servletContext.getContextPath()); + } +} diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java b/ethereumj/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java new file mode 100644 index 0000000000..c3a5143fdb --- /dev/null +++ b/ethereumj/src/main/java/com/baeldung/ethereumj/listeners/EthListener.java @@ -0,0 +1,71 @@ +package com.baeldung.ethereumj.listeners; + +import org.ethereum.core.Block; +import org.ethereum.core.TransactionReceipt; +import org.ethereum.facade.Ethereum; +import org.ethereum.listener.EthereumListenerAdapter; +import org.ethereum.util.BIUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.List; + +public class EthListener extends EthereumListenerAdapter { + + private Logger l = LoggerFactory.getLogger(EthListener.class); + private Ethereum ethereum; + private boolean syncDone = false; + private static final int thou = 1000; + + private void out(String t) { + l.info(t); + } + + private String calcNetHashRate(Block block) { + String response = "Net hash rate not available"; + if (block.getNumber() > thou) { + long timeDelta = 0; + for (int i = 0; i < thou; ++i) { + Block parent = ethereum + .getBlockchain() + .getBlockByHash(block.getParentHash()); + timeDelta += Math.abs(block.getTimestamp() - parent.getTimestamp()); + } + response = String.valueOf(block + .getDifficultyBI() + .divide(BIUtil.toBI(timeDelta / thou)) + .divide(new BigInteger("1000000000")) + .doubleValue()) + " GH/s"; + } + return response; + } + + public EthListener(Ethereum ethereum) { + this.ethereum = ethereum; + } + + @Override + public void onBlock(Block block, List receipts) { + if (syncDone) { + out("Net hash rate: " + calcNetHashRate(block)); + out("Block difficulty: " + block.getDifficultyBI().toString()); + out("Block transactions: " + block.getTransactionsList().toString()); + out("Best block (last block): " + ethereum + .getBlockchain() + .getBestBlock().toString()); + out("Total difficulty: " + ethereum + .getBlockchain() + .getTotalDifficulty().toString()); + } + } + + @Override + public void onSyncDone(SyncState state) { + out("onSyncDone " + state); + if (!syncDone) { + out(" ** SYNC DONE ** "); + syncDone = true; + } + } +} \ No newline at end of file diff --git a/ethereumj/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java b/ethereumj/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java new file mode 100644 index 0000000000..e8cfb3113b --- /dev/null +++ b/ethereumj/src/main/java/com/baeldung/ethereumj/transfer/EthResponse.java @@ -0,0 +1,14 @@ +package com.baeldung.ethereumj.transfer; + +public class EthResponse { + + private String response; + + public String getResponse() { + return response; + } + + public void setResponse(String response) { + this.response = response; + } +} diff --git a/ethereumj/src/main/resources/application.properties b/ethereumj/src/main/resources/application.properties new file mode 100644 index 0000000000..033e543fe8 --- /dev/null +++ b/ethereumj/src/main/resources/application.properties @@ -0,0 +1,2 @@ +server.servlet-path=/ +server.port=8080 \ No newline at end of file diff --git a/ethereumj/src/test/java/com/baeldung/ethereumj/controllers/EthControllerTestOne.java b/ethereumj/src/test/java/com/baeldung/ethereumj/controllers/EthControllerTestOne.java new file mode 100644 index 0000000000..9298c34ec2 --- /dev/null +++ b/ethereumj/src/test/java/com/baeldung/ethereumj/controllers/EthControllerTestOne.java @@ -0,0 +1,72 @@ +package com.baeldung.ethereumj.controllers; + +import com.baeldung.ethereumj.ApplicationMain; +import com.baeldung.ethereumj.Constants; +import com.baeldung.ethereumj.transfer.EthResponse; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.*; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.client.RestTemplate; + +import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.assertNotNull; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ApplicationMain.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@TestPropertySource(properties = "server.port=8080") +public class EthControllerTestOne { + + @LocalServerPort + int port; + + private RestTemplate restTemplate = new RestTemplate(); + + private String url(String uri) { + String s = "http://localhost:" + port + uri; + System.out.println(s); + return s; + } + + @Before + public void setup() { + restTemplate = new RestTemplate(); + } + + @Test() + public void bestBlockTest() throws Exception { + + Thread.sleep(20000); + + EthResponse a = restTemplate.getForObject(url(Constants.ENDPOINT_ONE), EthResponse.class); + assertNotNull(a); + + ResponseEntity b = restTemplate.exchange( + url(Constants.ENDPOINT_ONE), + HttpMethod.GET, new HttpEntity(null, new HttpHeaders()), EthResponse.class); + + assertTrue("Status 200?", b.getStatusCode().equals(HttpStatus.OK)); + System.out.println("Status 200?: " + b.getStatusCode().equals(HttpStatus.OK)); + assertTrue("Dynamic data returned?", b.hasBody()); + System.out.println("Dynamic data returned?: " + b.hasBody()); + } + + @Test() + public void difficultyTest() throws Exception { + + Thread.sleep(20000); + + ResponseEntity a = restTemplate.exchange( + url(Constants.ENDPOINT_TWO), + HttpMethod.GET, new HttpEntity(null, new HttpHeaders()), EthResponse.class); + + assertTrue("Status 200?", a.getStatusCode().equals(HttpStatus.OK)); + System.out.println("Status 200?: " + a.getStatusCode().equals(HttpStatus.OK)); + assertTrue("Dynamic data returned?", a.hasBody()); + System.out.println("Dynamic data returned?: " + a.hasBody()); + } +} diff --git a/events/README.md b/events/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/events/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/feign/README.md b/feign/README.md index 4d6964a73a..da04c40cdc 100644 --- a/feign/README.md +++ b/feign/README.md @@ -5,4 +5,6 @@ This is the implementation of a [spring-hypermedia-api][1] client using Feign. [1]: https://github.com/eugenp/spring-hypermedia-api ### Relevant Articles: + - [Intro to Feign](http://www.baeldung.com/intro-to-feign) +- [Introduction to SLF4J](http://www.baeldung.com/slf4j-with-log4j2-logback) diff --git a/geotools/README.md b/geotools/README.md new file mode 100644 index 0000000000..188ff0fddb --- /dev/null +++ b/geotools/README.md @@ -0,0 +1,3 @@ +### Relevant Articles + +[Introduction to GeoTools](http://www.baeldung.com/geo-tools) diff --git a/geotools/pom.xml b/geotools/pom.xml new file mode 100644 index 0000000000..37b4a2338a --- /dev/null +++ b/geotools/pom.xml @@ -0,0 +1,74 @@ + + 4.0.0 + + com.baeldung + geotools + 0.0.1-SNAPSHOT + jar + + geotools + http://maven.apache.org + + + + junit + junit + 4.12 + test + + + org.geotools + gt-shapefile + ${geotools-shapefile.version} + + + org.geotools + gt-epsg-hsql + ${geotools.version} + + + org.geotools + gt-swing + ${geotools-swing.version} + + + + + maven2-repository.dev.java.net + Java.net repository + http://download.java.net/maven/2 + + + osgeo + Open Source Geospatial Foundation Repository + http://download.osgeo.org/webdav/geotools/ + + + + true + + opengeo + OpenGeo Maven Repository + http://repo.opengeo.org + + + + + + true + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + 15.2 + 15.2 + 15.2 + + diff --git a/libraries/src/main/java/com/baeldung/geotools/ShapeFile.java b/geotools/src/main/java/com/baeldung/geotools/ShapeFile.java similarity index 71% rename from libraries/src/main/java/com/baeldung/geotools/ShapeFile.java rename to geotools/src/main/java/com/baeldung/geotools/ShapeFile.java index 77c67abc84..de789918cd 100644 --- a/libraries/src/main/java/com/baeldung/geotools/ShapeFile.java +++ b/geotools/src/main/java/com/baeldung/geotools/ShapeFile.java @@ -1,12 +1,8 @@ package com.baeldung.geotools; -import java.io.File; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.Point; import org.geotools.data.DataUtilities; import org.geotools.data.DefaultTransaction; import org.geotools.data.Transaction; @@ -23,9 +19,13 @@ import org.geotools.swing.data.JFileDataStoreChooser; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; -import com.vividsolutions.jts.geom.Coordinate; -import com.vividsolutions.jts.geom.GeometryFactory; -import com.vividsolutions.jts.geom.Point; +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; public class ShapeFile { @@ -41,22 +41,117 @@ public class ShapeFile { SimpleFeatureType CITY = createFeatureType(); - SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(CITY); - - addLocations(featureBuilder, collection); + addLocations(CITY, collection); File shapeFile = getNewShapeFile(); ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory(); Map params = new HashMap(); + + ShapefileDataStore dataStore = setDataStoreParams(dataStoreFactory, params, shapeFile, CITY); + + writeToFile(dataStore, collection); + } + + static SimpleFeatureType createFeatureType() { + + SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); + builder.setName("Location"); + builder.setCRS(DefaultGeographicCRS.WGS84); + + builder.add("Location", Point.class); + builder.length(15) + .add("Name", String.class); + + return builder.buildFeatureType(); + } + + static void addLocations(SimpleFeatureType CITY, DefaultFeatureCollection collection) { + + Map> locations = new HashMap<>(); + + double lat = 13.752222; + double lng = 100.493889; + addToLocationMap("Bangkok", lat, lng, locations); + + lat = 53.083333; + lng = -0.15; + addToLocationMap("New York", lat, lng, locations); + + lat = -33.925278; + lng = 18.423889; + addToLocationMap("Cape Town", lat, lng, locations); + + lat = -33.859972; + lng = 151.211111; + addToLocationMap("Sydney", lat, lng, locations); + + lat = 45.420833; + lng = -75.69; + addToLocationMap("Ottawa", lat, lng, locations); + + lat = 30.07708; + lng = 31.285909; + addToLocationMap("Cairo", lat, lng, locations); + + GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null); + + locations.entrySet().stream() + .map(toFeature(CITY, geometryFactory)) + .forEach(collection::add); + } + + private static Function>, SimpleFeature> toFeature(SimpleFeatureType CITY, GeometryFactory geometryFactory) { + return location -> { + Point point = geometryFactory.createPoint( + new Coordinate(location.getValue() + .get(0), location.getValue().get(1))); + + SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(CITY); + featureBuilder.add(point); + featureBuilder.add(location.getKey()); + return featureBuilder.buildFeature(null); + }; + } + + private static void addToLocationMap(String name, double lat, double lng, Map> locations) { + List coordinates = new ArrayList<>(); + + coordinates.add(lat); + coordinates.add(lng); + locations.put(name, coordinates); + } + + private static File getNewShapeFile() { + String filePath = new File(".").getAbsolutePath() + FILE_NAME; + + JFileDataStoreChooser chooser = new JFileDataStoreChooser("shp"); + chooser.setDialogTitle("Save shapefile"); + chooser.setSelectedFile(new File(filePath)); + + int returnVal = chooser.showSaveDialog(null); + + if (returnVal != JFileDataStoreChooser.APPROVE_OPTION) { + System.exit(0); + } + + return chooser.getSelectedFile(); + } + + private static ShapefileDataStore setDataStoreParams(ShapefileDataStoreFactory dataStoreFactory, Map params, File shapeFile, SimpleFeatureType CITY) throws Exception { params.put("url", shapeFile.toURI() - .toURL()); + .toURL()); params.put("create spatial index", Boolean.TRUE); ShapefileDataStore dataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params); dataStore.createSchema(CITY); + return dataStore; + } + + private static void writeToFile(ShapefileDataStore dataStore, DefaultFeatureCollection collection) throws Exception { + // If you decide to use the TYPE type and create a Data Store with it, // You will need to uncomment this line to set the Coordinate Reference System // newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); @@ -73,11 +168,9 @@ public class ShapeFile { try { featureStore.addFeatures(collection); transaction.commit(); - } catch (Exception problem) { problem.printStackTrace(); transaction.rollback(); - } finally { transaction.close(); } @@ -86,102 +179,5 @@ public class ShapeFile { System.out.println(typeName + " does not support read/write access"); System.exit(1); } - } - - public static SimpleFeatureType createFeatureType() { - - SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); - builder.setName("Location"); - builder.setCRS(DefaultGeographicCRS.WGS84); - - builder.add("Location", Point.class); - builder.length(15) - .add("Name", String.class); - - SimpleFeatureType CITY = builder.buildFeatureType(); - - return CITY; - } - - public static void addLocations(SimpleFeatureBuilder featureBuilder, DefaultFeatureCollection collection) { - - Map> locations = new HashMap<>(); - - double lat = 13.752222; - double lng = 100.493889; - String name = "Bangkok"; - addToLocationMap(name, lat, lng, locations); - - lat = 53.083333; - lng = -0.15; - name = "New York"; - addToLocationMap(name, lat, lng, locations); - - lat = -33.925278; - lng = 18.423889; - name = "Cape Town"; - addToLocationMap(name, lat, lng, locations); - - lat = -33.859972; - lng = 151.211111; - name = "Sydney"; - addToLocationMap(name, lat, lng, locations); - - lat = 45.420833; - lng = -75.69; - name = "Ottawa"; - addToLocationMap(name, lat, lng, locations); - - lat = 30.07708; - lng = 31.285909; - name = "Cairo"; - addToLocationMap(name, lat, lng, locations); - - GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null); - - for (Map.Entry> location : locations.entrySet()) { - Point point = geometryFactory.createPoint(new Coordinate(location.getValue() - .get(0), - location.getValue() - .get(1))); - featureBuilder.add(point); - featureBuilder.add(name); - SimpleFeature feature = featureBuilder.buildFeature(null); - collection.add(feature); - } - - } - - private static void addToLocationMap(String name, double lat, double lng, Map> locations) { - List coordinates = new ArrayList<>(); - - coordinates.add(lat); - coordinates.add(lng); - locations.put(name, coordinates); - } - - private static File getNewShapeFile() { - String filePath = new File(".").getAbsolutePath() + FILE_NAME; - - - JFileDataStoreChooser chooser = new JFileDataStoreChooser("shp"); - chooser.setDialogTitle("Save shapefile"); - chooser.setSelectedFile(new File(filePath)); - - int returnVal = chooser.showSaveDialog(null); - - if (returnVal != JFileDataStoreChooser.APPROVE_OPTION) { - System.exit(0); - } - - File shapeFile = chooser.getSelectedFile(); - if (shapeFile.equals(filePath)) { - System.out.println("Error: cannot replace " + filePath); - System.exit(0); - } - - return shapeFile; - } - } diff --git a/libraries/src/test/java/com/baeldung/geotools/GeoToolsUnitTestTest.java b/geotools/src/test/java/com/baeldung/geotools/GeoToolsUnitTest.java similarity index 75% rename from libraries/src/test/java/com/baeldung/geotools/GeoToolsUnitTestTest.java rename to geotools/src/test/java/com/baeldung/geotools/GeoToolsUnitTest.java index 44cd47edc3..053932b2a7 100644 --- a/libraries/src/test/java/com/baeldung/geotools/GeoToolsUnitTestTest.java +++ b/geotools/src/test/java/com/baeldung/geotools/GeoToolsUnitTest.java @@ -7,21 +7,16 @@ import org.geotools.feature.simple.SimpleFeatureBuilder; import org.junit.Test; import org.opengis.feature.simple.SimpleFeatureType; -public class GeoToolsUnitTestTest { +public class GeoToolsUnitTest { @Test public void givenFeatureType_whenAddLocations_returnFeatureCollection() { - DefaultFeatureCollection collection = new DefaultFeatureCollection(); SimpleFeatureType CITY = ShapeFile.createFeatureType(); - SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(CITY); - - ShapeFile.addLocations(featureBuilder, collection); + ShapeFile.addLocations(CITY, collection); assertNotNull(collection); - } - } diff --git a/gradle/.gitignore b/gradle/.gitignore new file mode 100644 index 0000000000..da88288c09 --- /dev/null +++ b/gradle/.gitignore @@ -0,0 +1 @@ +/.gradle/ diff --git a/gradle/.travis.yml b/gradle/.travis.yml new file mode 100644 index 0000000000..b2b534799b --- /dev/null +++ b/gradle/.travis.yml @@ -0,0 +1,27 @@ +# More details on how to configure the Travis build +# https://docs.travis-ci.com/user/customizing-the-build/ + +# Speed up build with travis caches +cache: + directories: + - $HOME/.gradle/caches/ + - $HOME/.gradle/wrapper/ + +language: java + +jdk: + - oraclejdk8 + +#Skipping install step to avoid having Travis run arbitrary './gradlew assemble' task +# https://docs.travis-ci.com/user/customizing-the-build/#Skipping-the-Installation-Step +install: + - true + +#Don't build tags +branches: + except: + - /^v\d/ + +#Build and perform release (if needed) +script: + - ./gradlew build -s && ./gradlew ciPerformRelease \ No newline at end of file diff --git a/gradle/README.md b/gradle/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/gradle/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/gradle/build.gradle b/gradle/build.gradle index fc561987f7..dcc592a2b4 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -1,25 +1,35 @@ -apply plugin: 'java' -apply plugin: 'maven' - -repositories{ - mavenCentral() +allprojects { + repositories { + jcenter() + } } -dependencies{ - compile 'org.springframework:spring-context:4.3.5.RELEASE' -} -task hello { - println "this Baeldung's tutorial is ${awesomeness}" +subprojects { + + version = '1.0' } -uploadArchives { - repositories { - mavenDeployer { - repository(url: 'http://yourmavenrepo/repository') { - authentication(userName: 'user', password: 'password'); - } - - } - } +apply plugin: 'eclipse' + +println 'This will be executed during the configuration phase.' + +task configured { + println 'This will also be executed during the configuration phase.' +} + +task execFirstTest { + doLast { + println 'This will be executed during the execution phase.' + } +} + +task execSecondTest { + doFirst { + println 'This will be executed first during the execution phase.' + } + doLast { + println 'This will be executed last during the execution phase.' + } + println 'This will be executed during the configuration phase as well.' } diff --git a/gradle/gradle.properties b/gradle/gradle.properties deleted file mode 100644 index 41701e5a19..0000000000 --- a/gradle/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -awesomeness=awesome -group=com.baeldung.tutorial -version=1.0.1 diff --git a/gradle/gradle/shipkit.gradle b/gradle/gradle/shipkit.gradle new file mode 100644 index 0000000000..144c01dc05 --- /dev/null +++ b/gradle/gradle/shipkit.gradle @@ -0,0 +1,41 @@ +//This default Shipkit configuration file was created automatically and is intended to be checked-in. +//Default configuration is sufficient for local testing and trying out Shipkit. +//To leverage Shipkit fully, please fix the TODO items, refer to our Getting Started Guide for help: +// +// https://github.com/mockito/shipkit/blob/master/docs/getting-started.md +// +shipkit { + //TODO is the repository correct? + gitHub.repository = "unspecified-user/unspecified-repo" + + //TODO generate and use your own read-only GitHub personal access token + gitHub.readOnlyAuthToken = "76826c9ec886612f504d12fd4268b16721c4f85d" + + //TODO generate GitHub write token, and ensure your Travis CI has this env variable exported + gitHub.writeAuthToken = System.getenv("GH_WRITE_TOKEN") +} + +allprojects { + plugins.withId("com.jfrog.bintray") { + + //Bintray configuration is handled by JFrog Bintray Gradle Plugin + //For reference see the official documentation: https://github.com/bintray/gradle-bintray-plugin + bintray { + + //TODO sign up for free open source account with https://bintray.com, then look up your API key on your profile page in Bintray + key = '7ea297848ca948adb7d3ee92a83292112d7ae989' + //TODO don't check in the key, remove above line and use env variable exported on CI: + //key = System.getenv("BINTRAY_API_KEY") + + pkg { + //TODO configure Bintray settings per your project (https://github.com/bintray/gradle-bintray-plugin) + repo = 'bootstrap' + user = 'shipkit-bootstrap-bot' + userOrg = 'shipkit-bootstrap' + name = 'maven' + licenses = ['MIT'] + labels = ['continuous delivery', 'release automation', 'shipkit'] + } + } + } +} diff --git a/gradle/gradle/wrapper/gradle-wrapper.jar b/gradle/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 3391a4cdf6..0000000000 Binary files a/gradle/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle/gradle/wrapper/gradle-wrapper.properties index b601d97764..ebf7ae9184 100644 --- a/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Dec 31 15:46:08 BRT 2016 +#Thu Oct 12 16:43:02 BDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip diff --git a/gradle/gradletaskdemo/aplugin.gradle b/gradle/gradletaskdemo/aplugin.gradle new file mode 100644 index 0000000000..ca96c50b54 --- /dev/null +++ b/gradle/gradletaskdemo/aplugin.gradle @@ -0,0 +1,5 @@ +task fromPlugin { + doLast { + println "I'm from plugin" + } +} \ No newline at end of file diff --git a/gradle/gradletaskdemo/build.gradle b/gradle/gradletaskdemo/build.gradle new file mode 100644 index 0000000000..58dadd7460 --- /dev/null +++ b/gradle/gradletaskdemo/build.gradle @@ -0,0 +1,110 @@ +buildscript { + repositories { + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "org.shipkit:shipkit:0.9.117" + } +} + + +plugins { + id 'java' +} + + +apply from: 'aplugin.gradle' +apply plugin: 'org.shipkit.bintray-release' + + +//hello task +task hello { + doLast { + println 'Baeldung' + } +} + +//Groovy in gradle task +task toLower { + doLast { + String someString = 'HELLO FROM BAELDUNG' + println "Original: " + someString + println "Lower case: " + someString.toLowerCase() + } +} + + +// Task dependencies +task helloGradle { + doLast { + println 'Hello Gradle!' + } +} + +task fromBaeldung(dependsOn: helloGradle) { + doLast { + println "I'm from Baeldung" + } +} + + +//Adding behavior to a task via api +task helloBaeldung { + doLast { + println 'I will be executed second' + } +} + +helloBaeldung.doFirst { + println 'I will be executed first' +} + +helloBaeldung.doLast { + println 'I will be executed third' +} + +helloBaeldung { + doLast { + println 'I will be executed fourth' + } +} + + + + +//Adding extra task properties +task ourTask { + ext.theProperty = "theValue" +} + +task printTaskProperty { + doLast { + println ourTask.theProperty + } +} + + + +//Declaring dependencies +dependencies { + compile group: + 'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE' + compile 'org.springframework:spring-core:4.3.5.RELEASE', + 'org.springframework:spring-aop:4.3.5.RELEASE' + compile( + [group: 'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE'], + [group: 'org.springframework', name: 'spring-aop', version: '4.3.5.RELEASE'] + ) + testCompile('org.hibernate:hibernate-core:5.2.12.Final') { + transitive = true + } + runtime(group: 'org.hibernate', name: 'hibernate-core', version: '5.2.12.Final') { + transitive = false + } + runtime "org.codehaus.groovy:groovy-all:2.4.11@jar" + runtime group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.11', ext: 'jar' + + compile fileTree(dir: 'libs', include: '*.jar') +} diff --git a/gradle/gradletaskdemo/build/tmp/jar/MANIFEST.MF b/gradle/gradletaskdemo/build/tmp/jar/MANIFEST.MF new file mode 100644 index 0000000000..59499bce4a --- /dev/null +++ b/gradle/gradletaskdemo/build/tmp/jar/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/gradle/gradlew b/gradle/gradlew index 9d82f78915..27309d9231 100644 --- a/gradle/gradlew +++ b/gradle/gradlew @@ -6,12 +6,30 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,26 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then diff --git a/gradle/gradlew.bat b/gradle/gradlew.bat index 8a0b282aa6..832fdb6079 100644 --- a/gradle/gradlew.bat +++ b/gradle/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,7 +46,7 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args diff --git a/gradle/greeter/.gitignore b/gradle/greeter/.gitignore new file mode 100644 index 0000000000..e93e09f86e --- /dev/null +++ b/gradle/greeter/.gitignore @@ -0,0 +1,3 @@ +/.gradle +/build +/bin diff --git a/gradle/greeter/build.gradle b/gradle/greeter/build.gradle new file mode 100644 index 0000000000..6f43f23494 --- /dev/null +++ b/gradle/greeter/build.gradle @@ -0,0 +1,18 @@ +apply plugin : 'java' +apply plugin : 'application' + + + +dependencies { + compile project(':greeting-library') + compile project(':greeting-library-java') +} + +mainClassName = 'greeter.Greeter' +run { + if (project.hasProperty("appArgs")) { + args Eval.me(appArgs) + } + else + args = ["Baeldung"]; +} diff --git a/gradle/greeter/src/main/java/greeter/Greeter.java b/gradle/greeter/src/main/java/greeter/Greeter.java new file mode 100644 index 0000000000..7b59f0c4bc --- /dev/null +++ b/gradle/greeter/src/main/java/greeter/Greeter.java @@ -0,0 +1,13 @@ +package greeter; + +import baeldunggreeter.Formatter; + +public class Greeter { + public static void main(String[] args) { + final String output = GreetingFormatter + .greeting(args[0]); + String date = Formatter.getFormattedDate(); + System.out.println(output); + System.out.println("Today is :" + date); + } +} diff --git a/gradle/greeter/src/test/java/greetertest/TestGreeting.java b/gradle/greeter/src/test/java/greetertest/TestGreeting.java new file mode 100644 index 0000000000..0ae5fab631 --- /dev/null +++ b/gradle/greeter/src/test/java/greetertest/TestGreeting.java @@ -0,0 +1,11 @@ + + + + +public class TestGreeting{ + + + + + +} \ No newline at end of file diff --git a/gradle/greeting-library-java/.gitignore b/gradle/greeting-library-java/.gitignore new file mode 100644 index 0000000000..348c102afc --- /dev/null +++ b/gradle/greeting-library-java/.gitignore @@ -0,0 +1,2 @@ +/build +/bin diff --git a/gradle/greeting-library-java/build.gradle b/gradle/greeting-library-java/build.gradle new file mode 100644 index 0000000000..34931bd0cd --- /dev/null +++ b/gradle/greeting-library-java/build.gradle @@ -0,0 +1,9 @@ +apply plugin :'java' +//apply plugin : 'application' + + + +dependencies{ + compile group: 'joda-time', name: 'joda-time', version: '2.9.9' + testCompile group: 'junit', name: 'junit', version: '4.12' +} diff --git a/gradle/greeting-library-java/src/main/java/baeldunggreeter/Formatter.java b/gradle/greeting-library-java/src/main/java/baeldunggreeter/Formatter.java new file mode 100644 index 0000000000..367e992c1b --- /dev/null +++ b/gradle/greeting-library-java/src/main/java/baeldunggreeter/Formatter.java @@ -0,0 +1,14 @@ +package baeldunggreeter; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class Formatter { + public static String getFormattedDate() { + DateFormat dateFormat = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + Date date = new Date(); + return dateFormat.format(date); + } +} diff --git a/gradle/greeting-library-java/src/test/java/baeldunggreetertest/FormatterTest.java b/gradle/greeting-library-java/src/test/java/baeldunggreetertest/FormatterTest.java new file mode 100644 index 0000000000..49efc934a5 --- /dev/null +++ b/gradle/greeting-library-java/src/test/java/baeldunggreetertest/FormatterTest.java @@ -0,0 +1,23 @@ +package baeldunggreetertest; + +import static org.junit.Assert.assertTrue; + +import java.util.Date; +import java.util.regex.Pattern; + +import org.junit.Test; + +import baeldunggreeter.Formatter; + +public class FormatterTest { + + @Test + public void testFormatter() { + + String dateRegex1 = "^((19|20)\\d\\d)-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01]) ([2][0-3]|[0-1][0-9]|[1-9]):[0-5][0-9]:([0-5][0-9]|[6][0])$"; + String dateString = Formatter.getFormattedDate(); + assertTrue(Pattern + .matches(dateRegex1, dateString)); + + } +} \ No newline at end of file diff --git a/gradle/greeting-library/.gitignore b/gradle/greeting-library/.gitignore new file mode 100644 index 0000000000..84c048a73c --- /dev/null +++ b/gradle/greeting-library/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/gradle/greeting-library/bin/greeter/GreetingFormatter.groovy b/gradle/greeting-library/bin/greeter/GreetingFormatter.groovy new file mode 100644 index 0000000000..94c863e294 --- /dev/null +++ b/gradle/greeting-library/bin/greeter/GreetingFormatter.groovy @@ -0,0 +1,10 @@ +package greeter + +import groovy.transform.CompileStatic + +@CompileStatic +class GreetingFormatter{ + static String greeting(final String name) { + "Hello, ${name.capitalize()}" + } +} diff --git a/gradle/greeting-library/bin/greeter/GreetingFormatterSpec.groovy b/gradle/greeting-library/bin/greeter/GreetingFormatterSpec.groovy new file mode 100644 index 0000000000..f1c1211552 --- /dev/null +++ b/gradle/greeting-library/bin/greeter/GreetingFormatterSpec.groovy @@ -0,0 +1,13 @@ +package greeter + +import spock.lang.Specification + +class GreetingFormatterSpec extends Specification { + + def 'Creating a greeting'() { + + expect: 'The greeeting to be correctly capitalized' + GreetingFormatter.greeting('gradlephant') == 'Hello, Gradlephant' + + } +} diff --git a/gradle/greeting-library/build.gradle b/gradle/greeting-library/build.gradle new file mode 100644 index 0000000000..eb526b3b03 --- /dev/null +++ b/gradle/greeting-library/build.gradle @@ -0,0 +1,9 @@ +apply plugin : 'groovy' + +dependencies { + compile 'org.codehaus.groovy:groovy:2.4.12' + + testCompile 'org.spockframework:spock-core:1.0-groovy-2.4', { + exclude module : 'groovy-all' + } +} diff --git a/gradle/greeting-library/src/main/groovy/greeter/GreetingFormatter.groovy b/gradle/greeting-library/src/main/groovy/greeter/GreetingFormatter.groovy new file mode 100644 index 0000000000..db8a035b67 --- /dev/null +++ b/gradle/greeting-library/src/main/groovy/greeter/GreetingFormatter.groovy @@ -0,0 +1,10 @@ +package greeter + +import groovy.transform.CompileStatic + +@CompileStatic +class GreetingFormatter{ + static String greeting(final String name) { + "Hello, ${name.capitalize()}" + } +} \ No newline at end of file diff --git a/gradle/greeting-library/src/test/groovy/greeter/GreetingFormatterSpec.groovy b/gradle/greeting-library/src/test/groovy/greeter/GreetingFormatterSpec.groovy new file mode 100644 index 0000000000..f1c1211552 --- /dev/null +++ b/gradle/greeting-library/src/test/groovy/greeter/GreetingFormatterSpec.groovy @@ -0,0 +1,13 @@ +package greeter + +import spock.lang.Specification + +class GreetingFormatterSpec extends Specification { + + def 'Creating a greeting'() { + + expect: 'The greeeting to be correctly capitalized' + GreetingFormatter.greeting('gradlephant') == 'Hello, Gradlephant' + + } +} diff --git a/gradle/settings.gradle b/gradle/settings.gradle new file mode 100644 index 0000000000..38704681bd --- /dev/null +++ b/gradle/settings.gradle @@ -0,0 +1,10 @@ +rootProject.name = 'gradletutorial' + + +include 'greeting-library' +include 'greeting-library-java' +include 'greeter' +include 'gradletaskdemo' + + +println 'This will be executed during the initialization phase.' diff --git a/gradle/src/main/java/Main.java b/gradle/src/main/java/Main.java deleted file mode 100644 index 10edd1840b..0000000000 --- a/gradle/src/main/java/Main.java +++ /dev/null @@ -1,5 +0,0 @@ -public class Main{ - public static void main(String[] args){ - System.out.println("Baeldung Rocks"); - } -} diff --git a/gradle/version.properties b/gradle/version.properties new file mode 100644 index 0000000000..565e9213ae --- /dev/null +++ b/gradle/version.properties @@ -0,0 +1,3 @@ +#Version of the produced binaries. This file is intended to be checked-in. +#It will be automatically bumped by release automation. +version=0.0.1 diff --git a/graphql/graphql-java/README.md b/graphql/graphql-java/README.md new file mode 100644 index 0000000000..0033524209 --- /dev/null +++ b/graphql/graphql-java/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Introduction to GraphQL](http://www.baeldung.com/graphql) diff --git a/grpc/README.md b/grpc/README.md new file mode 100644 index 0000000000..5a60ca2e7e --- /dev/null +++ b/grpc/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to gRPC](http://www.baeldung.com/grpc-introduction) diff --git a/guava-modules/README.md b/guava-modules/README.md new file mode 100644 index 0000000000..79e45a89e7 --- /dev/null +++ b/guava-modules/README.md @@ -0,0 +1,3 @@ + +## Guava Modules + diff --git a/guava18/README.md b/guava-modules/guava-18/README.md similarity index 100% rename from guava18/README.md rename to guava-modules/guava-18/README.md diff --git a/guava18/pom.xml b/guava-modules/guava-18/pom.xml similarity index 89% rename from guava18/pom.xml rename to guava-modules/guava-18/pom.xml index 0b96918171..f8dbf5657e 100644 --- a/guava18/pom.xml +++ b/guava-modules/guava-18/pom.xml @@ -4,13 +4,14 @@ 4.0.0 com.baeldung - guava18 + guava-18 0.1.0-SNAPSHOT com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/guava18/src/main/java/com/baeldung/guava/entity/Administrator.java b/guava-modules/guava-18/src/main/java/com/baeldung/guava/entity/Administrator.java similarity index 100% rename from guava18/src/main/java/com/baeldung/guava/entity/Administrator.java rename to guava-modules/guava-18/src/main/java/com/baeldung/guava/entity/Administrator.java diff --git a/guava18/src/main/java/com/baeldung/guava/entity/Player.java b/guava-modules/guava-18/src/main/java/com/baeldung/guava/entity/Player.java similarity index 100% rename from guava18/src/main/java/com/baeldung/guava/entity/Player.java rename to guava-modules/guava-18/src/main/java/com/baeldung/guava/entity/Player.java diff --git a/guava18/src/main/java/com/baeldung/guava/entity/User.java b/guava-modules/guava-18/src/main/java/com/baeldung/guava/entity/User.java similarity index 100% rename from guava18/src/main/java/com/baeldung/guava/entity/User.java rename to guava-modules/guava-18/src/main/java/com/baeldung/guava/entity/User.java diff --git a/guava18/src/test/java/com/baeldung/guava/FluentIterableUnitTest.java b/guava-modules/guava-18/src/test/java/com/baeldung/guava/FluentIterableUnitTest.java similarity index 100% rename from guava18/src/test/java/com/baeldung/guava/FluentIterableUnitTest.java rename to guava-modules/guava-18/src/test/java/com/baeldung/guava/FluentIterableUnitTest.java diff --git a/guava18/src/test/java/com/baeldung/guava/GuavaMiscUtilsTest.java b/guava-modules/guava-18/src/test/java/com/baeldung/guava/GuavaMiscUtilsTest.java similarity index 100% rename from guava18/src/test/java/com/baeldung/guava/GuavaMiscUtilsTest.java rename to guava-modules/guava-18/src/test/java/com/baeldung/guava/GuavaMiscUtilsTest.java diff --git a/guava18/src/test/java/com/baeldung/guava/MoreExecutorsUnitTest.java b/guava-modules/guava-18/src/test/java/com/baeldung/guava/MoreExecutorsUnitTest.java similarity index 100% rename from guava18/src/test/java/com/baeldung/guava/MoreExecutorsUnitTest.java rename to guava-modules/guava-18/src/test/java/com/baeldung/guava/MoreExecutorsUnitTest.java diff --git a/guava18/src/test/java/com/baeldung/guava/MoreObjectsUnitTest.java b/guava-modules/guava-18/src/test/java/com/baeldung/guava/MoreObjectsUnitTest.java similarity index 100% rename from guava18/src/test/java/com/baeldung/guava/MoreObjectsUnitTest.java rename to guava-modules/guava-18/src/test/java/com/baeldung/guava/MoreObjectsUnitTest.java diff --git a/guava19/README.md b/guava-modules/guava-19/README.md similarity index 100% rename from guava19/README.md rename to guava-modules/guava-19/README.md diff --git a/guava19/pom.xml b/guava-modules/guava-19/pom.xml similarity index 89% rename from guava19/pom.xml rename to guava-modules/guava-19/pom.xml index af9bc51eb9..4a23bf7aec 100644 --- a/guava19/pom.xml +++ b/guava-modules/guava-19/pom.xml @@ -4,13 +4,14 @@ 4.0.0 com.baeldung - guava19 + guava-19 0.1.0-SNAPSHOT com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/guava19/src/main/java/com/baeldung/guava/entity/User.java b/guava-modules/guava-19/src/main/java/com/baeldung/guava/entity/User.java similarity index 100% rename from guava19/src/main/java/com/baeldung/guava/entity/User.java rename to guava-modules/guava-19/src/main/java/com/baeldung/guava/entity/User.java diff --git a/guava19/src/test/java/com/baeldung/guava/CharMatcherUnitTest.java b/guava-modules/guava-19/src/test/java/com/baeldung/guava/CharMatcherUnitTest.java similarity index 100% rename from guava19/src/test/java/com/baeldung/guava/CharMatcherUnitTest.java rename to guava-modules/guava-19/src/test/java/com/baeldung/guava/CharMatcherUnitTest.java diff --git a/guava19/src/test/java/com/baeldung/guava/GuavaMiscUtilsTest.java b/guava-modules/guava-19/src/test/java/com/baeldung/guava/GuavaMiscUtilsTest.java similarity index 100% rename from guava19/src/test/java/com/baeldung/guava/GuavaMiscUtilsTest.java rename to guava-modules/guava-19/src/test/java/com/baeldung/guava/GuavaMiscUtilsTest.java diff --git a/guava19/src/test/java/com/baeldung/guava/HashingUnitTest.java b/guava-modules/guava-19/src/test/java/com/baeldung/guava/HashingUnitTest.java similarity index 100% rename from guava19/src/test/java/com/baeldung/guava/HashingUnitTest.java rename to guava-modules/guava-19/src/test/java/com/baeldung/guava/HashingUnitTest.java diff --git a/guava19/src/test/java/com/baeldung/guava/TypeTokenUnitTest.java b/guava-modules/guava-19/src/test/java/com/baeldung/guava/TypeTokenUnitTest.java similarity index 100% rename from guava19/src/test/java/com/baeldung/guava/TypeTokenUnitTest.java rename to guava-modules/guava-19/src/test/java/com/baeldung/guava/TypeTokenUnitTest.java diff --git a/guava21/README.md b/guava-modules/guava-21/README.md similarity index 73% rename from guava21/README.md rename to guava-modules/guava-21/README.md index 2a54416e41..68c1ac4a8e 100644 --- a/guava21/README.md +++ b/guava-modules/guava-21/README.md @@ -1,3 +1,4 @@ ### Relevant articles: - [New Stream, Comparator and Collector Functionality in Guava 21](http://www.baeldung.com/guava-21-new) - [New in Guava 21 common.util.concurrent](http://www.baeldung.com/guava-21-util-concurrent) +- [Zipping Collections in Java](http://www.baeldung.com/java-collections-zip) diff --git a/guava21/pom.xml b/guava-modules/guava-21/pom.xml similarity index 89% rename from guava21/pom.xml rename to guava-modules/guava-21/pom.xml index 930def2a67..f5432fb7df 100644 --- a/guava21/pom.xml +++ b/guava-modules/guava-21/pom.xml @@ -4,13 +4,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - guava21 + guava-21 1.0-SNAPSHOT com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/AtomicLongMapTutorials.java b/guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/AtomicLongMapTutorials.java similarity index 100% rename from guava21/src/main/java/com/baeldung/guava/tutorial/AtomicLongMapTutorials.java rename to guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/AtomicLongMapTutorials.java diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/ComparatorsExamples.java b/guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/ComparatorsExamples.java similarity index 100% rename from guava21/src/main/java/com/baeldung/guava/tutorial/ComparatorsExamples.java rename to guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/ComparatorsExamples.java diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/ConcatStreams.java b/guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/ConcatStreams.java similarity index 100% rename from guava21/src/main/java/com/baeldung/guava/tutorial/ConcatStreams.java rename to guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/ConcatStreams.java diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/InternerBuilderExample.java b/guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/InternerBuilderExample.java similarity index 100% rename from guava21/src/main/java/com/baeldung/guava/tutorial/InternerBuilderExample.java rename to guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/InternerBuilderExample.java diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/MonitorExample.java b/guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/MonitorExample.java similarity index 100% rename from guava21/src/main/java/com/baeldung/guava/tutorial/MonitorExample.java rename to guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/MonitorExample.java diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/MoreCollectorsExample.java b/guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/MoreCollectorsExample.java similarity index 100% rename from guava21/src/main/java/com/baeldung/guava/tutorial/MoreCollectorsExample.java rename to guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/MoreCollectorsExample.java diff --git a/guava21/src/main/java/com/baeldung/guava/tutorial/StreamsUtility.java b/guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/StreamsUtility.java similarity index 100% rename from guava21/src/main/java/com/baeldung/guava/tutorial/StreamsUtility.java rename to guava-modules/guava-21/src/main/java/com/baeldung/guava/tutorial/StreamsUtility.java diff --git a/guava21/src/test/java/com.baeldung.guava.zip/ZipCollectionTest.java b/guava-modules/guava-21/src/test/java/com.baeldung.guava.zip/ZipCollectionTest.java similarity index 100% rename from guava21/src/test/java/com.baeldung.guava.zip/ZipCollectionTest.java rename to guava-modules/guava-21/src/test/java/com.baeldung.guava.zip/ZipCollectionTest.java diff --git a/guava21/src/test/java/com/baeldung/guava/tutorial/AtomicLongMapIntegrationTest.java b/guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/AtomicLongMapIntegrationTest.java similarity index 100% rename from guava21/src/test/java/com/baeldung/guava/tutorial/AtomicLongMapIntegrationTest.java rename to guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/AtomicLongMapIntegrationTest.java diff --git a/guava21/src/test/java/com/baeldung/guava/tutorial/ComparatorsUnitTest.java b/guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/ComparatorsUnitTest.java similarity index 100% rename from guava21/src/test/java/com/baeldung/guava/tutorial/ComparatorsUnitTest.java rename to guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/ComparatorsUnitTest.java diff --git a/guava21/src/test/java/com/baeldung/guava/tutorial/GuavaStreamsUnitTest.java b/guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/GuavaStreamsUnitTest.java similarity index 100% rename from guava21/src/test/java/com/baeldung/guava/tutorial/GuavaStreamsUnitTest.java rename to guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/GuavaStreamsUnitTest.java diff --git a/guava21/src/test/java/com/baeldung/guava/tutorial/InternBuilderUnitTest.java b/guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/InternBuilderUnitTest.java similarity index 100% rename from guava21/src/test/java/com/baeldung/guava/tutorial/InternBuilderUnitTest.java rename to guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/InternBuilderUnitTest.java diff --git a/guava21/src/test/java/com/baeldung/guava/tutorial/MonitorUnitTest.java b/guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/MonitorUnitTest.java similarity index 100% rename from guava21/src/test/java/com/baeldung/guava/tutorial/MonitorUnitTest.java rename to guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/MonitorUnitTest.java diff --git a/guava21/src/test/java/com/baeldung/guava/tutorial/MoreCollectorsUnitTest.java b/guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/MoreCollectorsUnitTest.java similarity index 100% rename from guava21/src/test/java/com/baeldung/guava/tutorial/MoreCollectorsUnitTest.java rename to guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/MoreCollectorsUnitTest.java diff --git a/guava21/src/test/java/com/baeldung/guava/tutorial/StreamUtility.java b/guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/StreamUtility.java similarity index 100% rename from guava21/src/test/java/com/baeldung/guava/tutorial/StreamUtility.java rename to guava-modules/guava-21/src/test/java/com/baeldung/guava/tutorial/StreamUtility.java diff --git a/guest/README.md b/guest/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/guest/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/guest/spring-mvc/README.md b/guest/spring-mvc/README.md new file mode 100644 index 0000000000..9e5cd64a04 --- /dev/null +++ b/guest/spring-mvc/README.md @@ -0,0 +1,17 @@ +## Building + +To build the module, use Maven's `package` goal: + +``` +mvn clean package +``` + +## Running + +To run the application, use Spring Boot's `run` goal: + +``` +mvn spring-boot:run +``` + +The application will be accessible at [http://localhost:8080/](http://localhost:8080/) diff --git a/guest/spring-mvc/pom.xml b/guest/spring-mvc/pom.xml new file mode 100644 index 0000000000..1f695a75a7 --- /dev/null +++ b/guest/spring-mvc/pom.xml @@ -0,0 +1,59 @@ + + + 4.0.0 + + com.stackify.guest + spring-mvc + 0.0.1-SNAPSHOT + jar + + spring-mvc + Spring MVC sample project + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.M5 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + UTF-8 + UTF-8 + 1.8 + + + diff --git a/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/Spring5Application.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/Spring5Application.java new file mode 100644 index 0000000000..42d40fa02d --- /dev/null +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/Spring5Application.java @@ -0,0 +1,15 @@ +package com.stackify.guest.springmvc; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.boot.SpringApplication; + +@SpringBootApplication +@ComponentScan(basePackages = {"com.stackify.guest.springmvc"}) +public class Spring5Application { + + public static void main(String[] args) { + SpringApplication.run(Spring5Application.class, args); + } + +} diff --git a/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/model/LoginData.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/model/LoginData.java new file mode 100644 index 0000000000..b1a0e86ef4 --- /dev/null +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/model/LoginData.java @@ -0,0 +1,27 @@ +package com.stackify.guest.springmvc.model; + +public class LoginData { + + private String login; + + private String password; + + public LoginData() { + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/InternalsController.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/InternalsController.java new file mode 100644 index 0000000000..0bd8570eed --- /dev/null +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/InternalsController.java @@ -0,0 +1,40 @@ +package com.stackify.guest.springmvc.web; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +import com.stackify.guest.springmvc.model.LoginData; + +import java.util.Collections; + +@Controller +public class InternalsController { + + private static final String LOGIN = "jack"; + private static final String PASSWORD = "halloween"; + + @GetMapping("/") + public String hello() { + return "login"; + } + + @PostMapping("/login") + public ModelAndView login(LoginData loginData) { + if (LOGIN.equals(loginData.getLogin()) && PASSWORD.equals(loginData.getPassword())) { + return new ModelAndView("success", Collections.singletonMap("login", loginData.getLogin())); + } else { + return new ModelAndView("failure", Collections.singletonMap("login", loginData.getLogin())); + } + } + + @ResponseBody + @PostMapping("/message") + public MyOutputResource sendMessage(@RequestBody MyInputResource inputResource) { + return new MyOutputResource("Received: " + inputResource.getRequestMessage()); + } + +} diff --git a/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyInputResource.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyInputResource.java new file mode 100644 index 0000000000..cf5815840a --- /dev/null +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyInputResource.java @@ -0,0 +1,14 @@ +package com.stackify.guest.springmvc.web; + +public class MyInputResource { + + private String requestMessage; + + public String getRequestMessage() { + return requestMessage; + } + + public void setRequestMessage(String requestMessage) { + this.requestMessage = requestMessage; + } +} diff --git a/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyOutputResource.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyOutputResource.java new file mode 100644 index 0000000000..2d0e174243 --- /dev/null +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyOutputResource.java @@ -0,0 +1,15 @@ +package com.stackify.guest.springmvc.web; + +public class MyOutputResource { + + private String responseMessage; + + public MyOutputResource(String responseMessage) { + this.responseMessage = responseMessage; + } + + public String getResponseMessage() { + return responseMessage; + } + +} diff --git a/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/RestfulWebServiceController.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/RestfulWebServiceController.java new file mode 100644 index 0000000000..edb35e6ecf --- /dev/null +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/RestfulWebServiceController.java @@ -0,0 +1,14 @@ +package com.stackify.guest.springmvc.web; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class RestfulWebServiceController { + + @GetMapping("/message") + public MyOutputResource getMessage() { + return new MyOutputResource("Hello!"); + } + +} diff --git a/guest/spring-mvc/src/main/resources/templates/failure.html b/guest/spring-mvc/src/main/resources/templates/failure.html new file mode 100644 index 0000000000..f319652ede --- /dev/null +++ b/guest/spring-mvc/src/main/resources/templates/failure.html @@ -0,0 +1,10 @@ + + + + Login Failure + +

    + User with login not found, please try again. +

    + \ No newline at end of file diff --git a/guest/spring-mvc/src/main/resources/templates/login.html b/guest/spring-mvc/src/main/resources/templates/login.html new file mode 100644 index 0000000000..d031ac8825 --- /dev/null +++ b/guest/spring-mvc/src/main/resources/templates/login.html @@ -0,0 +1,13 @@ + + +Login Form + + +
    + + + +
    + + + \ No newline at end of file diff --git a/guest/spring-mvc/src/main/resources/templates/success.html b/guest/spring-mvc/src/main/resources/templates/success.html new file mode 100644 index 0000000000..6966385f2e --- /dev/null +++ b/guest/spring-mvc/src/main/resources/templates/success.html @@ -0,0 +1,10 @@ + + + + Login Success + +

    + Hello, ! +

    + \ No newline at end of file diff --git a/guest/spring-security/README.md b/guest/spring-security/README.md new file mode 100644 index 0000000000..9e5cd64a04 --- /dev/null +++ b/guest/spring-security/README.md @@ -0,0 +1,17 @@ +## Building + +To build the module, use Maven's `package` goal: + +``` +mvn clean package +``` + +## Running + +To run the application, use Spring Boot's `run` goal: + +``` +mvn spring-boot:run +``` + +The application will be accessible at [http://localhost:8080/](http://localhost:8080/) diff --git a/guest/spring-security/pom.xml b/guest/spring-security/pom.xml new file mode 100644 index 0000000000..c41637bfc2 --- /dev/null +++ b/guest/spring-security/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + + com.stackify.guest + spring-security + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.M6 + + + + spring-security + Spring Security Sample Project + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.thymeleaf + thymeleaf-spring5 + 3.0.8.RELEASE + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-jdbc + + + com.h2database + h2 + runtime + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + UTF-8 + UTF-8 + 1.8 + + + \ No newline at end of file diff --git a/guest/spring-security/src/main/java/com/stackify/guest/springsecurity/Application.java b/guest/spring-security/src/main/java/com/stackify/guest/springsecurity/Application.java new file mode 100644 index 0000000000..fbd0eee044 --- /dev/null +++ b/guest/spring-security/src/main/java/com/stackify/guest/springsecurity/Application.java @@ -0,0 +1,15 @@ +package com.stackify.guest.springsecurity; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = {"com.stackify.guest.springsecurity"}) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/guest/spring-security/src/main/java/com/stackify/guest/springsecurity/config/WebMvcConfiguration.java b/guest/spring-security/src/main/java/com/stackify/guest/springsecurity/config/WebMvcConfiguration.java new file mode 100644 index 0000000000..b8dfe9050d --- /dev/null +++ b/guest/spring-security/src/main/java/com/stackify/guest/springsecurity/config/WebMvcConfiguration.java @@ -0,0 +1,16 @@ +package com.stackify.guest.springsecurity.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebMvcConfiguration implements WebMvcConfigurer { + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/customLogin").setViewName("customLogin"); + registry.addViewController("/loginSuccess").setViewName("index"); + } + +} \ No newline at end of file diff --git a/guest/spring-security/src/main/java/com/stackify/guest/springsecurity/config/WebSecurityConfig.java b/guest/spring-security/src/main/java/com/stackify/guest/springsecurity/config/WebSecurityConfig.java new file mode 100644 index 0000000000..164808d5b3 --- /dev/null +++ b/guest/spring-security/src/main/java/com/stackify/guest/springsecurity/config/WebSecurityConfig.java @@ -0,0 +1,40 @@ +package com.stackify.guest.springsecurity.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.JdbcUserDetailsManager; + +import javax.sql.DataSource; + +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Bean + public UserDetailsService jdbcUserDetailsService(DataSource dataSource) { + JdbcUserDetailsManager manager = new JdbcUserDetailsManager(); + manager.setDataSource(dataSource); + return manager; + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/css/**").permitAll() + .anyRequest().authenticated() + .and().formLogin() + .loginPage("/customLogin") + .defaultSuccessUrl("/loginSuccess", true) + .permitAll(); + } + +} \ No newline at end of file diff --git a/guest/spring-security/src/main/resources/data.sql b/guest/spring-security/src/main/resources/data.sql new file mode 100644 index 0000000000..b3f7db9105 --- /dev/null +++ b/guest/spring-security/src/main/resources/data.sql @@ -0,0 +1,2 @@ +INSERT INTO users VALUES ('jill', '$2a$04$qUlqAEEYF1YvrpJMosodoewgL6aO.qgHytl2k5L7kdXEWnJsFdxvq', TRUE); +INSERT INTO authorities VALUES ('jill', 'USERS'); diff --git a/guest/spring-security/src/main/resources/schema.sql b/guest/spring-security/src/main/resources/schema.sql new file mode 100644 index 0000000000..3de1b9a29f --- /dev/null +++ b/guest/spring-security/src/main/resources/schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE users ( + username VARCHAR(256) PRIMARY KEY, + password VARCHAR(256), + enabled BOOLEAN +); + +CREATE TABLE authorities ( + username VARCHAR(256) REFERENCES users (username), + authority VARCHAR(256) +); diff --git a/guest/spring-security/src/main/resources/static/css/styles.css b/guest/spring-security/src/main/resources/static/css/styles.css new file mode 100644 index 0000000000..72bcc4934f --- /dev/null +++ b/guest/spring-security/src/main/resources/static/css/styles.css @@ -0,0 +1,3 @@ +.bad-login { + color: red; +} \ No newline at end of file diff --git a/guest/spring-security/src/main/resources/templates/customLogin.html b/guest/spring-security/src/main/resources/templates/customLogin.html new file mode 100644 index 0000000000..c689c78514 --- /dev/null +++ b/guest/spring-security/src/main/resources/templates/customLogin.html @@ -0,0 +1,21 @@ + + + + + + +
    +
    + + + + +
    + + + +
    Log out successful.
    +
    + + \ No newline at end of file diff --git a/guest/spring-security/src/main/resources/templates/index.html b/guest/spring-security/src/main/resources/templates/index.html new file mode 100644 index 0000000000..0769f9015f --- /dev/null +++ b/guest/spring-security/src/main/resources/templates/index.html @@ -0,0 +1,11 @@ + + +

    Hello, !

    +
    + + +
    + \ No newline at end of file diff --git a/guest/tomcat-app/WebContent/META-INF/MANIFEST.MF b/guest/tomcat-app/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/guest/tomcat-app/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/guest/tomcat-app/WebContent/WEB-INF/web.xml b/guest/tomcat-app/WebContent/WEB-INF/web.xml new file mode 100644 index 0000000000..efc7c9ae0d --- /dev/null +++ b/guest/tomcat-app/WebContent/WEB-INF/web.xml @@ -0,0 +1,28 @@ + + + tomcat-app + + tomcat-app + org.glassfish.jersey.servlet.ServletContainer + + javax.ws.rs.Application + com.stackify.ApplicationInitializer + + 1 + + + tomcat-app + /* + + + javamelody + net.bull.javamelody.MonitoringFilter + + gzip-compression-disabled + true + + + \ No newline at end of file diff --git a/guest/tomcat-app/pom.xml b/guest/tomcat-app/pom.xml new file mode 100644 index 0000000000..e62c6f78d8 --- /dev/null +++ b/guest/tomcat-app/pom.xml @@ -0,0 +1,70 @@ + + 4.0.0 + com.stackify + tomcat-app + 0.0.1-SNAPSHOT + war + + + + org.glassfish.jersey.containers + jersey-container-servlet + 2.25.1 + + + org.glassfish.jersey.media + jersey-media-moxy + 2.25.1 + + + io.rest-assured + rest-assured + 3.0.3 + + + junit + junit + 4.12 + + + + com.h2database + h2 + 1.4.195 + + + + org.apache.logging.log4j + log4j-core + 2.8.2 + + + + net.bull.javamelody + javamelody-core + 1.69.0 + + + + + + + + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + maven-war-plugin + 3.0.0 + + WebContent + + + + + \ No newline at end of file diff --git a/guest/tomcat-app/src/main/java/com/stackify/ApplicationInitializer.java b/guest/tomcat-app/src/main/java/com/stackify/ApplicationInitializer.java new file mode 100644 index 0000000000..6d864e859e --- /dev/null +++ b/guest/tomcat-app/src/main/java/com/stackify/ApplicationInitializer.java @@ -0,0 +1,9 @@ +package com.stackify; + +import org.glassfish.jersey.server.ResourceConfig; + +public class ApplicationInitializer extends ResourceConfig { + public ApplicationInitializer() { + packages("com.stackify.services"); + } +} diff --git a/guest/tomcat-app/src/main/java/com/stackify/daos/UserDAO.java b/guest/tomcat-app/src/main/java/com/stackify/daos/UserDAO.java new file mode 100644 index 0000000000..b57b230135 --- /dev/null +++ b/guest/tomcat-app/src/main/java/com/stackify/daos/UserDAO.java @@ -0,0 +1,67 @@ +package com.stackify.daos; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.stackify.models.User; +import com.stackify.utils.ConnectionUtil; + +public class UserDAO { + + private Logger logger = LogManager.getLogger(UserDAO.class); + + public void createTable() { + try (Connection con = ConnectionUtil.getConnection()) { + String createQuery = "CREATE TABLE IF NOT EXISTS users(email varchar(50) primary key, name varchar(50))"; + PreparedStatement pstmt = con.prepareStatement(createQuery); + + pstmt.execute(); + } catch (SQLException exc) { + logger.error(exc.getMessage()); + } + + } + + public void add(User user) { + try (Connection con = ConnectionUtil.getConnection()) { + + String insertQuery = "INSERT INTO users(email,name) VALUES(?,?)"; + PreparedStatement pstmt = con.prepareStatement(insertQuery); + pstmt.setString(1, user.getEmail()); + pstmt.setString(2, user.getName()); + + pstmt.executeUpdate(); + } catch (SQLException exc) { + logger.error(exc.getMessage()); + } + } + + public List findAll() { + List users = new ArrayList<>(); + + try (Connection con = ConnectionUtil.getConnection()) { + String query = "SELECT * FROM users"; + PreparedStatement pstmt = con.prepareStatement(query); + + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + User user = new User(); + user.setEmail(rs.getString("email")); + user.setName(rs.getString("name")); + users.add(user); + } + } catch (SQLException exc) { + logger.error(exc.getMessage()); + } + + return users; + } + +} diff --git a/guest/tomcat-app/src/main/java/com/stackify/models/User.java b/guest/tomcat-app/src/main/java/com/stackify/models/User.java new file mode 100644 index 0000000000..8c8073357d --- /dev/null +++ b/guest/tomcat-app/src/main/java/com/stackify/models/User.java @@ -0,0 +1,43 @@ +package com.stackify.models; + +import javax.ws.rs.core.Link; + +public class User { + private String email; + private String name; + private Link link; + + public User() { + } + + public User(String email, String name) { + super(); + this.email = email; + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Link getLink() { + return link; + } + + public void setLink(Link link) { + this.link = link; + } + +} diff --git a/guest/tomcat-app/src/main/java/com/stackify/services/CorsFilter.java b/guest/tomcat-app/src/main/java/com/stackify/services/CorsFilter.java new file mode 100644 index 0000000000..267aa6fd61 --- /dev/null +++ b/guest/tomcat-app/src/main/java/com/stackify/services/CorsFilter.java @@ -0,0 +1,19 @@ +package com.stackify.services; + +import java.io.IOException; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.ext.Provider; + +@Provider +public class CorsFilter implements ContainerResponseFilter { + + @Override + public void filter(final ContainerRequestContext requestContext, + final ContainerResponseContext response) throws IOException { + response.getHeaders().add("Access-Control-Allow-Origin", "*"); + response.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept"); + } +} diff --git a/guest/tomcat-app/src/main/java/com/stackify/services/UserService.java b/guest/tomcat-app/src/main/java/com/stackify/services/UserService.java new file mode 100644 index 0000000000..6cdb3eb55f --- /dev/null +++ b/guest/tomcat-app/src/main/java/com/stackify/services/UserService.java @@ -0,0 +1,37 @@ +package com.stackify.services; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import com.stackify.daos.UserDAO; +import com.stackify.models.User; + +@Path("/users") +public class UserService { + private UserDAO userDao = new UserDAO(); + + public UserService (){ + userDao.createTable(); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + public Response addUser(User user) { + userDao.add(user); + return Response.ok() + .build(); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public List getUsers() { + return userDao.findAll(); + } +} diff --git a/guest/tomcat-app/src/main/java/com/stackify/utils/ConnectionUtil.java b/guest/tomcat-app/src/main/java/com/stackify/utils/ConnectionUtil.java new file mode 100644 index 0000000000..e7734f64a7 --- /dev/null +++ b/guest/tomcat-app/src/main/java/com/stackify/utils/ConnectionUtil.java @@ -0,0 +1,38 @@ +package com.stackify.utils; + +import java.sql.Connection; +import java.sql.SQLException; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class ConnectionUtil { + + private static Logger logger = LogManager.getLogger(ConnectionUtil.class); + + public static Connection getConnection() { + try { + String jndiName = "java:/comp/env/jdbc/MyDataSource"; + + Context initialContext = new InitialContext(); + DataSource datasource = (DataSource)initialContext.lookup(jndiName); + if (datasource != null) { + return datasource.getConnection(); + } + else { + logger.error("Failed to lookup datasource."); + } + } + + catch (NamingException | SQLException exc) { + logger.error(exc.getMessage()); + } + return null; + } + +} diff --git a/handling-spring-static-resources/README.md b/handling-spring-static-resources/README.md index d8f64bc427..c12e0272d4 100644 --- a/handling-spring-static-resources/README.md +++ b/handling-spring-static-resources/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Cachable Static Assets with Spring MVC](http://www.baeldung.com/cachable-static-assets-with-spring-mvc) - [Minification of JS and CSS Assets with Maven](http://www.baeldung.com/maven-minification-of-js-and-css-assets) +- [Serve Static Resources with Spring](http://www.baeldung.com/spring-mvc-static-resources) diff --git a/hibernate5/README.md b/hibernate5/README.md new file mode 100644 index 0000000000..4690ebbe76 --- /dev/null +++ b/hibernate5/README.md @@ -0,0 +1,4 @@ +## Relevant articles: + +- [Dynamic Mapping with Hibernate](http://www.baeldung.com/hibernate-dynamic-mapping) +- [An Overview of Identifiers in Hibernate](http://www.baeldung.com/hibernate-identifiers) diff --git a/hibernate5/pom.xml b/hibernate5/pom.xml index c501b7f11d..3b0b2fcd88 100644 --- a/hibernate5/pom.xml +++ b/hibernate5/pom.xml @@ -17,23 +17,47 @@ UTF-8 3.6.0 - + 5.2.12.Final + 6.0.6 + 2.2.3 + org.hibernate hibernate-core - 5.2.9.Final + ${hibernate.version} junit junit 4.12 + + org.assertj + assertj-core + 3.8.0 + test + com.h2database h2 1.4.194 + + org.hibernate + hibernate-spatial + ${hibernate.version} + + + mysql + mysql-connector-java + ${mysql.version} + + + ch.vorburger.mariaDB4j + mariaDB4j + ${mariaDB4j.version} + hibernate5 diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateMultiTenantUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateMultiTenantUtil.java index 5a10b2ba56..30f3c3cf53 100644 --- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateMultiTenantUtil.java +++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateMultiTenantUtil.java @@ -68,7 +68,7 @@ public class HibernateMultiTenantUtil { Properties properties = new Properties(); URL propertiesURL = Thread.currentThread() .getContextClassLoader() - .getResource("hibernate.properties"); + .getResource("hibernate-multitenancy.properties"); FileInputStream inputStream = new FileInputStream(propertiesURL.getFile()); properties.load(inputStream); System.out.println("LOADED PROPERTIES FROM hibernate.properties"); diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java index c1f7301d46..f1fc22d29a 100644 --- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -1,24 +1,105 @@ package com.baeldung.hibernate; +import com.baeldung.hibernate.pojo.Employee; +import com.baeldung.hibernate.pojo.EntityDescription; +import com.baeldung.hibernate.pojo.OrderEntry; +import com.baeldung.hibernate.pojo.OrderEntryIdClass; +import com.baeldung.hibernate.pojo.OrderEntryPK; +import com.baeldung.hibernate.pojo.PointEntity; +import com.baeldung.hibernate.pojo.Product; +import com.baeldung.hibernate.pojo.Phone; +import com.baeldung.hibernate.pojo.TemporalValues; +import com.baeldung.hibernate.pojo.Course; +import com.baeldung.hibernate.pojo.Student; +import com.baeldung.hibernate.pojo.User; +import com.baeldung.hibernate.pojo.UserProfile; +import com.baeldung.hibernate.pojo.inheritance.Animal; +import com.baeldung.hibernate.pojo.inheritance.Bag; +import com.baeldung.hibernate.pojo.inheritance.Book; +import com.baeldung.hibernate.pojo.inheritance.Car; +import com.baeldung.hibernate.pojo.inheritance.MyEmployee; +import com.baeldung.hibernate.pojo.inheritance.MyProduct; +import com.baeldung.hibernate.pojo.inheritance.Pen; +import com.baeldung.hibernate.pojo.inheritance.Person; +import com.baeldung.hibernate.pojo.inheritance.Pet; +import com.baeldung.hibernate.pojo.inheritance.Vehicle; + +import org.apache.commons.lang3.StringUtils; import org.hibernate.SessionFactory; -import org.hibernate.cfg.Configuration; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.service.ServiceRegistry; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; public class HibernateUtil { + private static SessionFactory sessionFactory; + private static String PROPERTY_FILE_NAME; - private static final SessionFactory sessionFactory; - - static { - try { - Configuration configuration = new Configuration().configure(); - sessionFactory = configuration.buildSessionFactory(); - - } catch (Throwable ex) { - System.err.println("Initial SessionFactory creation failed." + ex); - throw new ExceptionInInitializerError(ex); - } + public static SessionFactory getSessionFactory() throws IOException { + return getSessionFactory(null); } - public static SessionFactory getSessionFactory() { + public static SessionFactory getSessionFactory(String propertyFileName) throws IOException { + PROPERTY_FILE_NAME = propertyFileName; + if (sessionFactory == null) { + ServiceRegistry serviceRegistry = configureServiceRegistry(); + sessionFactory = makeSessionFactory(serviceRegistry); + } return sessionFactory; } + + private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) { + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + metadataSources.addPackage("com.baeldung.hibernate.pojo"); + metadataSources.addAnnotatedClass(Employee.class); + metadataSources.addAnnotatedClass(Phone.class); + metadataSources.addAnnotatedClass(EntityDescription.class); + metadataSources.addAnnotatedClass(TemporalValues.class); + metadataSources.addAnnotatedClass(User.class); + metadataSources.addAnnotatedClass(Student.class); + metadataSources.addAnnotatedClass(Course.class); + metadataSources.addAnnotatedClass(Product.class); + metadataSources.addAnnotatedClass(OrderEntryPK.class); + metadataSources.addAnnotatedClass(OrderEntry.class); + metadataSources.addAnnotatedClass(OrderEntryIdClass.class); + metadataSources.addAnnotatedClass(UserProfile.class); + metadataSources.addAnnotatedClass(Book.class); + metadataSources.addAnnotatedClass(MyEmployee.class); + metadataSources.addAnnotatedClass(MyProduct.class); + metadataSources.addAnnotatedClass(Pen.class); + metadataSources.addAnnotatedClass(Person.class); + metadataSources.addAnnotatedClass(Animal.class); + metadataSources.addAnnotatedClass(Pet.class); + metadataSources.addAnnotatedClass(Vehicle.class); + metadataSources.addAnnotatedClass(Car.class); + metadataSources.addAnnotatedClass(Bag.class); + metadataSources.addAnnotatedClass(PointEntity.class); + + Metadata metadata = metadataSources.buildMetadata(); + return metadata.getSessionFactoryBuilder() + .build(); + + } + + private static ServiceRegistry configureServiceRegistry() throws IOException { + Properties properties = getProperties(); + return new StandardServiceRegistryBuilder().applySettings(properties) + .build(); + } + + private static Properties getProperties() throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread() + .getContextClassLoader() + .getResource(StringUtils.defaultString(PROPERTY_FILE_NAME, "hibernate.properties")); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } } \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Course.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Course.java new file mode 100644 index 0000000000..97760acd3b --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Course.java @@ -0,0 +1,27 @@ +package com.baeldung.hibernate.pojo; + +import java.util.UUID; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Course { + + @Id + @GeneratedValue + private UUID courseId; + + public UUID getCourseId() { + return courseId; + } + + public void setCourseId(UUID courseId) { + this.courseId = courseId; + } + + + + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Department.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Department.java new file mode 100644 index 0000000000..6dd106b88e --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Department.java @@ -0,0 +1,25 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.TableGenerator; + +@Entity +public class Department { + @Id + @GeneratedValue(strategy = GenerationType.TABLE, generator="table-generator") + @TableGenerator (name="table-generator", table="dep_ids", pkColumnName="seq_id", valueColumnName="seq_value") + private long depId; + + public long getDepId() { + return depId; + } + + public void setDepId(long depId) { + this.depId = depId; + } + + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Employee.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Employee.java new file mode 100644 index 0000000000..e9732b2b67 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Employee.java @@ -0,0 +1,87 @@ +package com.baeldung.hibernate.pojo; + +import org.hibernate.annotations.*; + +import javax.persistence.Entity; +import javax.persistence.*; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +@Entity +@Where(clause = "deleted = false") +@FilterDef(name = "incomeLevelFilter", parameters = @ParamDef(name = "incomeLimit", type = "int")) +@Filter(name = "incomeLevelFilter", condition = "grossIncome > :incomeLimit") +public class Employee implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + private long grossIncome; + + private int taxInPercents; + + private boolean deleted; + + public long getTaxJavaWay() { + return grossIncome * taxInPercents / 100; + } + + @Formula("grossIncome * taxInPercents / 100") + private long tax; + + @OneToMany + @JoinColumn(name = "employee_id") + @Where(clause = "deleted = false") + private Set phones = new HashSet<>(0); + + public Employee() { + } + + public Employee(long grossIncome, int taxInPercents) { + this.grossIncome = grossIncome; + this.taxInPercents = taxInPercents; + } + + public Integer getId() { + return id; + } + + public long getGrossIncome() { + return grossIncome; + } + + public int getTaxInPercents() { + return taxInPercents; + } + + public long getTax() { + return tax; + } + + public void setId(Integer id) { + this.id = id; + } + + public void setGrossIncome(long grossIncome) { + this.grossIncome = grossIncome; + } + + public void setTaxInPercents(int taxInPercents) { + this.taxInPercents = taxInPercents; + } + + public boolean getDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + public Set getPhones() { + return phones; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/EntityDescription.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/EntityDescription.java new file mode 100644 index 0000000000..131bb73a80 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/EntityDescription.java @@ -0,0 +1,55 @@ +package com.baeldung.hibernate.pojo; + +import org.hibernate.annotations.Any; + +import javax.persistence.*; +import java.io.Serializable; + +@Entity +public class EntityDescription implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + private String description; + + @Any( + metaDef = "EntityDescriptionMetaDef", + metaColumn = @Column(name = "entity_type") + ) + @JoinColumn(name = "entity_id") + private Serializable entity; + + public EntityDescription() { + } + + public EntityDescription(String description, Serializable entity) { + this.description = description; + this.entity = entity; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Serializable getEntity() { + return entity; + } + + public void setEntity(Serializable entity) { + this.entity = entity; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/OrderEntry.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/OrderEntry.java new file mode 100644 index 0000000000..a28b7c8dbe --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/OrderEntry.java @@ -0,0 +1,20 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; + +@Entity +public class OrderEntry { + + @EmbeddedId + private OrderEntryPK entryId; + + public OrderEntryPK getEntryId() { + return entryId; + } + + public void setEntryId(OrderEntryPK entryId) { + this.entryId = entryId; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/OrderEntryIdClass.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/OrderEntryIdClass.java new file mode 100644 index 0000000000..18926640af --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/OrderEntryIdClass.java @@ -0,0 +1,31 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.IdClass; + +@Entity +@IdClass(OrderEntryPK.class) +public class OrderEntryIdClass { + @Id + private long orderId; + @Id + private long productId; + + public long getOrderId() { + return orderId; + } + + public void setOrderId(long orderId) { + this.orderId = orderId; + } + + public long getProductId() { + return productId; + } + + public void setProductId(long productId) { + this.productId = productId; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/OrderEntryPK.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/OrderEntryPK.java new file mode 100644 index 0000000000..637d590629 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/OrderEntryPK.java @@ -0,0 +1,46 @@ +package com.baeldung.hibernate.pojo; + +import java.io.Serializable; +import java.util.Objects; + +import javax.persistence.Embeddable; + +@Embeddable +public class OrderEntryPK implements Serializable { + + private long orderId; + private long productId; + + public long getOrderId() { + return orderId; + } + + public void setOrderId(long orderId) { + this.orderId = orderId; + } + + public long getProductId() { + return productId; + } + + public void setProductId(long productId) { + this.productId = productId; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + OrderEntryPK pk = (OrderEntryPK) o; + return Objects.equals(orderId, pk.orderId) && Objects.equals(productId, pk.productId); + } + + @Override + public int hashCode() { + return Objects.hash(orderId, productId); + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Phone.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Phone.java new file mode 100644 index 0000000000..d923bda5de --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Phone.java @@ -0,0 +1,50 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.io.Serializable; + +@Entity +public class Phone implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + private boolean deleted; + + private String number; + + public Phone() { + } + + public Phone(String number) { + this.number = number; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java new file mode 100644 index 0000000000..223f5dcbde --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java @@ -0,0 +1,41 @@ +package com.baeldung.hibernate.pojo; + +import com.vividsolutions.jts.geom.Point; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class PointEntity { + + @Id + @GeneratedValue + private Long id; + + private Point point; + + public PointEntity() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Point getPoint() { + return point; + } + + public void setPoint(Point point) { + this.point = point; + } + + @Override + public String toString() { + return "PointEntity{" + "id=" + id + ", point=" + point + '}'; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Product.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Product.java new file mode 100644 index 0000000000..efd6b63dc0 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Product.java @@ -0,0 +1,26 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Parameter; + +@Entity +public class Product { + + @Id + @GeneratedValue(generator = "prod-generator") + @GenericGenerator(name = "prod-generator", parameters = @Parameter(name = "prefix", value = "prod"), strategy = "com.baeldung.hibernate.pojo.generator.MyGenerator") + private String prodId; + + public String getProdId() { + return prodId; + } + + public void setProdId(String prodId) { + this.prodId = prodId; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Student.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Student.java new file mode 100644 index 0000000000..a6dec4a30d --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Student.java @@ -0,0 +1,23 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Student { + + @Id + @GeneratedValue (strategy = GenerationType.SEQUENCE) + private long studentId; + + public long getStudentId() { + return studentId; + } + + public void setStudent_id(long studentId) { + this.studentId = studentId; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java new file mode 100644 index 0000000000..f3fe095cae --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/TemporalValues.java @@ -0,0 +1,195 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; +import java.time.*; +import java.util.Calendar; + +@Entity +public class TemporalValues implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Basic + private java.sql.Date sqlDate; + + @Basic + private java.sql.Time sqlTime; + + @Basic + private java.sql.Timestamp sqlTimestamp; + + @Basic + @Temporal(TemporalType.DATE) + private java.util.Date utilDate; + + @Basic + @Temporal(TemporalType.TIME) + private java.util.Date utilTime; + + @Basic + @Temporal(TemporalType.TIMESTAMP) + private java.util.Date utilTimestamp; + + @Basic + @Temporal(TemporalType.DATE) + private java.util.Calendar calendarDate; + + @Basic + @Temporal(TemporalType.TIMESTAMP) + private java.util.Calendar calendarTimestamp; + + @Basic + private java.time.LocalDate localDate; + + @Basic + private java.time.LocalTime localTime; + + @Basic + private java.time.OffsetTime offsetTime; + + @Basic + private java.time.Instant instant; + + @Basic + private java.time.LocalDateTime localDateTime; + + @Basic + private java.time.OffsetDateTime offsetDateTime; + + @Basic + private java.time.ZonedDateTime zonedDateTime; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Date getSqlDate() { + return sqlDate; + } + + public void setSqlDate(Date sqlDate) { + this.sqlDate = sqlDate; + } + + public Time getSqlTime() { + return sqlTime; + } + + public void setSqlTime(Time sqlTime) { + this.sqlTime = sqlTime; + } + + public Timestamp getSqlTimestamp() { + return sqlTimestamp; + } + + public void setSqlTimestamp(Timestamp sqlTimestamp) { + this.sqlTimestamp = sqlTimestamp; + } + + public java.util.Date getUtilDate() { + return utilDate; + } + + public void setUtilDate(java.util.Date utilDate) { + this.utilDate = utilDate; + } + + public java.util.Date getUtilTime() { + return utilTime; + } + + public void setUtilTime(java.util.Date utilTime) { + this.utilTime = utilTime; + } + + public java.util.Date getUtilTimestamp() { + return utilTimestamp; + } + + public void setUtilTimestamp(java.util.Date utilTimestamp) { + this.utilTimestamp = utilTimestamp; + } + + public Calendar getCalendarDate() { + return calendarDate; + } + + public void setCalendarDate(Calendar calendarDate) { + this.calendarDate = calendarDate; + } + + public Calendar getCalendarTimestamp() { + return calendarTimestamp; + } + + public void setCalendarTimestamp(Calendar calendarTimestamp) { + this.calendarTimestamp = calendarTimestamp; + } + + public LocalDate getLocalDate() { + return localDate; + } + + public void setLocalDate(LocalDate localDate) { + this.localDate = localDate; + } + + public LocalTime getLocalTime() { + return localTime; + } + + public void setLocalTime(LocalTime localTime) { + this.localTime = localTime; + } + + public OffsetTime getOffsetTime() { + return offsetTime; + } + + public void setOffsetTime(OffsetTime offsetTime) { + this.offsetTime = offsetTime; + } + + public Instant getInstant() { + return instant; + } + + public void setInstant(Instant instant) { + this.instant = instant; + } + + public LocalDateTime getLocalDateTime() { + return localDateTime; + } + + public void setLocalDateTime(LocalDateTime localDateTime) { + this.localDateTime = localDateTime; + } + + public OffsetDateTime getOffsetDateTime() { + return offsetDateTime; + } + + public void setOffsetDateTime(OffsetDateTime offsetDateTime) { + this.offsetDateTime = offsetDateTime; + } + + public ZonedDateTime getZonedDateTime() { + return zonedDateTime; + } + + public void setZonedDateTime(ZonedDateTime zonedDateTime) { + this.zonedDateTime = zonedDateTime; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java new file mode 100644 index 0000000000..90203d29ec --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java @@ -0,0 +1,24 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; + +@Entity +public class User { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence-generator") + @SequenceGenerator(name = "sequence-generator", sequenceName = "user_sequence", initialValue = 4) + private long userId; + + public long getUserId() { + return userId; + } + + public void setUserId(long userId) { + this.userId = userId; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/UserProfile.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/UserProfile.java new file mode 100644 index 0000000000..ac870c2818 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/UserProfile.java @@ -0,0 +1,34 @@ +package com.baeldung.hibernate.pojo; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.MapsId; +import javax.persistence.OneToOne; + +@Entity +public class UserProfile { + + @Id + private long profileId; + + @OneToOne + @MapsId + private User user; + + public long getProfileId() { + return profileId; + } + + public void setProfileId(long profileId) { + this.profileId = profileId; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/generator/MyGenerator.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/generator/MyGenerator.java new file mode 100644 index 0000000000..17ffe9b7e1 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/generator/MyGenerator.java @@ -0,0 +1,41 @@ +package com.baeldung.hibernate.pojo.generator; + +import java.io.Serializable; +import java.util.Properties; +import java.util.stream.Stream; + +import org.hibernate.HibernateException; +import org.hibernate.MappingException; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.id.Configurable; +import org.hibernate.id.IdentifierGenerator; +import org.hibernate.service.ServiceRegistry; +import org.hibernate.type.Type; + +public class MyGenerator implements IdentifierGenerator, Configurable { + + private String prefix; + + @Override + public Serializable generate(SharedSessionContractImplementor session, Object obj) throws HibernateException { + + String query = String.format("select %s from %s", + session.getEntityPersister(obj.getClass().getName(), obj).getIdentifierPropertyName(), + obj.getClass().getSimpleName()); + + Stream ids = session.createQuery(query).stream(); + + Long max = ids.map(o -> o.replace(prefix + "-", "")) + .mapToLong(Long::parseLong) + .max() + .orElse(0L); + + return prefix + "-" + (max + 1); + } + + @Override + public void configure(Type type, Properties properties, ServiceRegistry serviceRegistry) throws MappingException { + prefix = properties.getProperty("prefix"); + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java new file mode 100644 index 0000000000..6fe7f915fc --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java @@ -0,0 +1,40 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; + +@Entity +@Inheritance(strategy = InheritanceType.JOINED) +public class Animal { + + @Id + private long animalId; + + private String species; + + public Animal() {} + + public Animal(long animalId, String species) { + this.animalId = animalId; + this.species = species; + } + + public long getAnimalId() { + return animalId; + } + + public void setAnimalId(long animalId) { + this.animalId = animalId; + } + + public String getSpecies() { + return species; + } + + public void setSpecies(String species) { + this.species = species; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java new file mode 100644 index 0000000000..fa6e1b4bef --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java @@ -0,0 +1,38 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; +import javax.persistence.Id; + +import org.hibernate.annotations.Polymorphism; +import org.hibernate.annotations.PolymorphismType; + +@Entity +@Polymorphism(type = PolymorphismType.EXPLICIT) +public class Bag implements Item { + + @Id + private long bagId; + + private String type; + + public Bag(long bagId, String type) { + this.bagId = bagId; + this.type = type; + } + + public long getBagId() { + return bagId; + } + + public void setBagId(long bagId) { + this.bagId = bagId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java new file mode 100644 index 0000000000..36ca8dd77c --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java @@ -0,0 +1,27 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +@Entity +@DiscriminatorValue("1") +public class Book extends MyProduct { + private String author; + + public Book() { + } + + public Book(long productId, String name, String author) { + super(productId, name); + this.author = author; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java new file mode 100644 index 0000000000..49d1f7749a --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java @@ -0,0 +1,25 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; + +@Entity +public class Car extends Vehicle { + private String engine; + + public Car() { + } + + public Car(long vehicleId, String manufacturer, String engine) { + super(vehicleId, manufacturer); + this.engine = engine; + } + + public String getEngine() { + return engine; + } + + public void setEngine(String engine) { + this.engine = engine; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Item.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Item.java new file mode 100644 index 0000000000..9656030736 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Item.java @@ -0,0 +1,5 @@ +package com.baeldung.hibernate.pojo.inheritance; + +public interface Item { + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java new file mode 100644 index 0000000000..9a6bce16cf --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java @@ -0,0 +1,22 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; + +@Entity +public class MyEmployee extends Person { + private String company; + + public MyEmployee(long personId, String name, String company) { + super(personId, name); + this.company = company; + } + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java new file mode 100644 index 0000000000..13f04d8904 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java @@ -0,0 +1,47 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.DiscriminatorColumn; +import javax.persistence.DiscriminatorType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; + +import org.hibernate.annotations.DiscriminatorFormula; + +@Entity +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +@DiscriminatorColumn(name = "product_type", discriminatorType = DiscriminatorType.INTEGER) +// @DiscriminatorFormula("case when author is not null then 1 else 2 end") +public class MyProduct { + @Id + private long productId; + + private String name; + + public MyProduct() { + } + + public MyProduct(long productId, String name) { + super(); + this.productId = productId; + this.name = name; + } + + public long getProductId() { + return productId; + } + + public void setProductId(long productId) { + this.productId = productId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java new file mode 100644 index 0000000000..32b77e52af --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java @@ -0,0 +1,27 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +@Entity +@DiscriminatorValue("2") +public class Pen extends MyProduct { + private String color; + + public Pen() { + } + + public Pen(long productId, String name, String color) { + super(productId, name); + this.color = color; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java new file mode 100644 index 0000000000..99084b88af --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java @@ -0,0 +1,38 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; + +@MappedSuperclass +public class Person { + + @Id + private long personId; + + private String name; + + public Person() { + } + + public Person(long personId, String name) { + this.personId = personId; + this.name = name; + } + + public long getPersonId() { + return personId; + } + + public void setPersonId(long personId) { + this.personId = personId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java new file mode 100644 index 0000000000..870b3cd684 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java @@ -0,0 +1,27 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; +import javax.persistence.PrimaryKeyJoinColumn; + +@Entity +@PrimaryKeyJoinColumn(name = "petId") +public class Pet extends Animal { + private String name; + + public Pet() { + } + + public Pet(long animalId, String species, String name) { + super(animalId, species); + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java new file mode 100644 index 0000000000..b2a920573e --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java @@ -0,0 +1,40 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; + +@Entity +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +public class Vehicle { + @Id + private long vehicleId; + + private String manufacturer; + + public Vehicle() { + } + + public Vehicle(long vehicleId, String manufacturer) { + this.vehicleId = vehicleId; + this.manufacturer = manufacturer; + } + + public long getVehicleId() { + return vehicleId; + } + + public void setVehicleId(long vehicleId) { + this.vehicleId = vehicleId; + } + + public String getManufacturer() { + return manufacturer; + } + + public void setManufacturer(String manufacturer) { + this.manufacturer = manufacturer; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/package-info.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/package-info.java new file mode 100644 index 0000000000..992cda7c1d --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/package-info.java @@ -0,0 +1,9 @@ +@AnyMetaDef(name = "EntityDescriptionMetaDef", metaType = "string", idType = "int", + metaValues = { + @MetaValue(value = "Employee", targetEntity = Employee.class), + @MetaValue(value = "Phone", targetEntity = Phone.class) + }) +package com.baeldung.hibernate.pojo; + +import org.hibernate.annotations.AnyMetaDef; +import org.hibernate.annotations.MetaValue; \ No newline at end of file diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java new file mode 100644 index 0000000000..b207d6630a --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java @@ -0,0 +1,164 @@ +package com.baeldung.hibernate; + +import com.baeldung.hibernate.pojo.Employee; +import com.baeldung.hibernate.pojo.EntityDescription; +import com.baeldung.hibernate.pojo.Phone; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DynamicMappingIntegrationTest { + + private Session session; + + private Transaction transaction; + + @Before + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory().openSession(); + transaction = session.beginTransaction(); + + session.createNativeQuery("delete from phone").executeUpdate(); + session.createNativeQuery("delete from employee").executeUpdate(); + + transaction.commit(); + transaction = session.beginTransaction(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + @Test + public void givenEntity_whenFieldMappedWithFormula_thenFieldIsCalculated() { + Employee employee = new Employee(10_000L, 25); + assertThat(employee.getTaxJavaWay()).isEqualTo(2_500L); + + session.save(employee); + session.flush(); + session.clear(); + + employee = session.get(Employee.class, employee.getId()); + assertThat(employee.getTax()).isEqualTo(2_500L); + } + + @Test + public void givenEntityMappedWithWhere_whenDeletedIsTrue_thenEntityNotFetched() { + Employee employee = new Employee(); + + session.save(employee); + session.clear(); + + employee = session.find(Employee.class, employee.getId()); + assertThat(employee).isNotNull(); + + employee.setDeleted(true); + session.flush(); + + employee = session.find(Employee.class, employee.getId()); + assertThat(employee).isNotNull(); + + session.clear(); + + employee = session.find(Employee.class, employee.getId()); + assertThat(employee).isNull(); + + } + + @Test + public void givenCollectionMappedWithWhere_whenDeletedIsTrue_thenEntityNotFetched() { + Employee employee = new Employee(); + Phone phone1 = new Phone("555-45-67"); + Phone phone2 = new Phone("555-89-01"); + employee.getPhones().add(phone1); + employee.getPhones().add(phone2); + + session.save(phone1); + session.save(phone2); + session.save(employee); + session.flush(); + session.clear(); + + employee = session.find(Employee.class, employee.getId()); + assertThat(employee.getPhones()).hasSize(2); + + employee.getPhones().iterator().next().setDeleted(true); + session.flush(); + session.clear(); + + employee = session.find(Employee.class, employee.getId()); + assertThat(employee.getPhones()).hasSize(1); + + List fullPhoneList = session.createQuery("from Phone").getResultList(); + assertThat(fullPhoneList).hasSize(2); + + } + + @Test + public void givenFilterByIncome_whenIncomeLimitSet_thenFilterIsApplied() throws IOException { + session.save(new Employee(10_000, 25)); + session.save(new Employee(12_000, 25)); + session.save(new Employee(15_000, 25)); + + session.flush(); + session.clear(); + + session.enableFilter("incomeLevelFilter") + .setParameter("incomeLimit", 11_000); + + List employees = session.createQuery("from Employee").getResultList(); + + assertThat(employees).hasSize(2); + + Employee employee = session.get(Employee.class, 1); + assertThat(employee.getGrossIncome()).isEqualTo(10_000); + + session.close(); + + session = HibernateUtil.getSessionFactory().openSession(); + transaction = session.beginTransaction(); + + employees = session.createQuery("from Employee").getResultList(); + + assertThat(employees).hasSize(3); + + } + + @Test + public void givenMappingWithAny_whenDescriptionAddedToEntity_thenDescriptionCanReferAnyEntity() { + Employee employee = new Employee(); + Phone phone1 = new Phone("555-45-67"); + Phone phone2 = new Phone("555-89-01"); + employee.getPhones().add(phone1); + employee.getPhones().add(phone2); + + EntityDescription employeeDescription = new EntityDescription("Send to conference next year", employee); + EntityDescription phone1Description = new EntityDescription("Home phone (do not call after 10PM)", phone1); + EntityDescription phone2Description = new EntityDescription("Work phone", phone1); + + session.save(phone1); + session.save(phone2); + session.save(employee); + session.save(employeeDescription); + session.save(phone1Description); + session.save(phone2Description); + session.flush(); + session.clear(); + + List descriptions = session.createQuery("from EntityDescription").getResultList(); + + assertThat(Employee.class.isAssignableFrom(descriptions.get(0).getEntity().getClass())).isTrue(); + assertThat(Phone.class.isAssignableFrom(descriptions.get(1).getEntity().getClass())).isTrue(); + assertThat(Phone.class.isAssignableFrom(descriptions.get(2).getEntity().getClass())).isTrue(); + } + +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java new file mode 100644 index 0000000000..a5c7b329fc --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java @@ -0,0 +1,97 @@ +package com.baeldung.hibernate; + +import com.baeldung.hibernate.pojo.PointEntity; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.persistence.Query; +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; + +import static org.junit.Assert.assertTrue; + +public class HibernateSpatialTest { + + private Session session; + private Transaction transaction; + + @Before + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory("hibernate-spatial.properties") + .openSession(); + transaction = session.beginTransaction(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + @Test + public void shouldConvertWktToGeometry() throws ParseException { + Geometry geometry = wktToGeometry("POINT (2 5)"); + assertEquals("Point", geometry.getGeometryType()); + assertTrue(geometry instanceof Point); + } + + @Test + public void shouldInsertAndSelectPoints() throws ParseException { + PointEntity entity = new PointEntity(); + entity.setPoint((Point) wktToGeometry("POINT (1 1)")); + + session.persist(entity); + PointEntity fromDb = session.find(PointEntity.class, entity.getId()); + assertEquals("POINT (1 1)", fromDb.getPoint().toString()); + } + + @Test + public void shouldSelectDisjointPoints() throws ParseException { + insertPoint("POINT (1 2)"); + insertPoint("POINT (3 4)"); + insertPoint("POINT (5 6)"); + + Point point = (Point) wktToGeometry("POINT (3 4)"); + Query query = session.createQuery("select p from PointEntity p " + + "where disjoint(p.point, :point) = true", PointEntity.class); + query.setParameter("point", point); + assertEquals("POINT (1 2)", ((PointEntity) query.getResultList().get(0)).getPoint().toString()); + assertEquals("POINT (5 6)", ((PointEntity) query.getResultList().get(1)).getPoint().toString()); + } + + @Test + public void shouldSelectAllPointsWithinPolygon() throws ParseException { + insertPoint("POINT (1 1)"); + insertPoint("POINT (1 2)"); + insertPoint("POINT (3 4)"); + insertPoint("POINT (5 6)"); + + Query query = session.createQuery("select p from PointEntity p where within(p.point, :area) = true", + PointEntity.class); + query.setParameter("area", wktToGeometry("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))")); + assertThat(query.getResultList().stream().map(p -> ((PointEntity) p).getPoint().toString())) + .containsOnly("POINT (1 1)", "POINT (1 2)", "POINT (3 4)"); + } + + private void insertPoint(String point) throws ParseException { + PointEntity entity = new PointEntity(); + entity.setPoint((Point) wktToGeometry(point)); + session.persist(entity); + } + + private Geometry wktToGeometry(String wellKnownText) throws ParseException { + WKTReader fromText = new WKTReader(); + Geometry geom = null; + geom = fromText.read(wellKnownText); + return geom; + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/IdentifiersIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/IdentifiersIntegrationTest.java new file mode 100644 index 0000000000..6b54dc80a8 --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/IdentifiersIntegrationTest.java @@ -0,0 +1,100 @@ +package com.baeldung.hibernate; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.hibernate.Transaction; +import java.io.IOException; +import org.hibernate.Session; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.baeldung.hibernate.pojo.Product; +import com.baeldung.hibernate.pojo.Course; +import com.baeldung.hibernate.pojo.OrderEntry; +import com.baeldung.hibernate.pojo.OrderEntryIdClass; +import com.baeldung.hibernate.pojo.OrderEntryPK; +import com.baeldung.hibernate.pojo.Student; +import com.baeldung.hibernate.pojo.User; +import com.baeldung.hibernate.pojo.UserProfile; + +public class IdentifiersIntegrationTest { + private Session session; + + private Transaction transaction; + + @Before + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory() + .openSession(); + transaction = session.beginTransaction(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + @Test + public void whenSaveSimpleIdEntities_thenOk() { + Student student = new Student(); + session.save(student); + User user = new User(); + session.save(user); + + assertThat(student.getStudentId()).isEqualTo(1L); + assertThat(user.getUserId()).isEqualTo(4L); + + Course course = new Course(); + session.save(course); + + } + + @Test + public void whenSaveCustomGeneratedId_thenOk() { + Product product = new Product(); + session.save(product); + Product product2 = new Product(); + session.save(product2); + + assertThat(product2.getProdId()).isEqualTo("prod-2"); + } + + @Test + public void whenSaveCompositeIdEntity_thenOk() { + OrderEntryPK entryPK = new OrderEntryPK(); + entryPK.setOrderId(1L); + entryPK.setProductId(30L); + + OrderEntry entry = new OrderEntry(); + entry.setEntryId(entryPK); + session.save(entry); + + assertThat(entry.getEntryId() + .getOrderId()).isEqualTo(1L); + } + + @Test + public void whenSaveIdClassEntity_thenOk() { + OrderEntryIdClass entry = new OrderEntryIdClass(); + entry.setOrderId(1L); + entry.setProductId(30L); + session.save(entry); + + assertThat(entry.getOrderId()).isEqualTo(1L); + } + + @Test + public void whenSaveDerivedIdEntity_thenOk() { + User user = new User(); + session.save(user); + + UserProfile profile = new UserProfile(); + profile.setUser(user); + session.save(profile); + + assertThat(profile.getProfileId()).isEqualTo(user.getUserId()); + } + +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java new file mode 100644 index 0000000000..0f35dbb8af --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java @@ -0,0 +1,89 @@ +package com.baeldung.hibernate; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.hibernate.pojo.inheritance.Bag; +import com.baeldung.hibernate.pojo.inheritance.Book; +import com.baeldung.hibernate.pojo.inheritance.Car; +import com.baeldung.hibernate.pojo.inheritance.MyEmployee; +import com.baeldung.hibernate.pojo.inheritance.Pen; +import com.baeldung.hibernate.pojo.inheritance.Pet; + +public class InheritanceMappingIntegrationTest { + private Session session; + + private Transaction transaction; + + @Before + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory() + .openSession(); + transaction = session.beginTransaction(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + @Test + public void givenSubclasses_whenQuerySingleTableSuperclass_thenOk() { + Book book = new Book(1, "1984", "George Orwell"); + session.save(book); + Pen pen = new Pen(2, "my pen", "blue"); + session.save(pen); + + assertThat(session.createQuery("from MyProduct") + .getResultList() + .size()).isEqualTo(2); + } + + @Test + public void givenSubclasses_whenQueryMappedSuperclass_thenOk() { + MyEmployee emp = new MyEmployee(1, "john", "baeldung"); + session.save(emp); + + assertThat(session.createQuery("from com.baeldung.hibernate.pojo.inheritance.Person") + .getResultList() + .size()).isEqualTo(1); + } + + @Test + public void givenSubclasses_whenQueryJoinedTableSuperclass_thenOk() { + Pet pet = new Pet(1, "dog", "lassie"); + session.save(pet); + + assertThat(session.createQuery("from Animal") + .getResultList() + .size()).isEqualTo(1); + } + + @Test + public void givenSubclasses_whenQueryTablePerClassSuperclass_thenOk() { + Car car = new Car(1, "audi", "xyz"); + session.save(car); + + assertThat(session.createQuery("from Vehicle") + .getResultList() + .size()).isEqualTo(1); + } + + @Test + public void givenSubclasses_whenQueryNonMappedInterface_thenOk() { + Bag bag = new Bag(1, "large"); + session.save(bag); + + assertThat(session.createQuery("from com.baeldung.hibernate.pojo.inheritance.Item") + .getResultList() + .size()).isEqualTo(0); + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesTest.java new file mode 100644 index 0000000000..ec8afc8db2 --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/TemporalValuesTest.java @@ -0,0 +1,126 @@ +package com.baeldung.hibernate; + +import com.baeldung.hibernate.pojo.TemporalValues; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.time.*; +import java.util.Calendar; +import java.util.TimeZone; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TemporalValuesTest { + + private Session session; + + private Transaction transaction; + + @Before + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory().withOptions() + .jdbcTimeZone(TimeZone.getTimeZone("UTC")) + .openSession(); + transaction = session.beginTransaction(); + session.createNativeQuery("delete from temporalvalues").executeUpdate(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + @Test + public void givenEntity_whenMappingSqlTypes_thenTemporalIsSelectedAutomatically() { + TemporalValues temporalValues = new TemporalValues(); + temporalValues.setSqlDate(java.sql.Date.valueOf("2017-11-15")); + temporalValues.setSqlTime(java.sql.Time.valueOf("15:30:14")); + temporalValues.setSqlTimestamp(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332")); + + session.save(temporalValues); + session.flush(); + session.clear(); + + temporalValues = session.get(TemporalValues.class, temporalValues.getId()); + assertThat(temporalValues.getSqlDate()).isEqualTo(java.sql.Date.valueOf("2017-11-15")); + assertThat(temporalValues.getSqlTime()).isEqualTo(java.sql.Time.valueOf("15:30:14")); + assertThat(temporalValues.getSqlTimestamp()).isEqualTo(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332")); + + } + + @Test + public void givenEntity_whenMappingUtilDateType_thenTemporalIsSpecifiedExplicitly() throws Exception { + TemporalValues temporalValues = new TemporalValues(); + temporalValues.setUtilDate(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15")); + temporalValues.setUtilTime(new SimpleDateFormat("HH:mm:ss").parse("15:30:14")); + temporalValues.setUtilTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.332")); + + session.save(temporalValues); + session.flush(); + session.clear(); + + temporalValues = session.get(TemporalValues.class, temporalValues.getId()); + assertThat(temporalValues.getUtilDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15")); + assertThat(temporalValues.getUtilTime()).isEqualTo(new SimpleDateFormat("HH:mm:ss").parse("15:30:14")); + assertThat(temporalValues.getUtilTimestamp()).isEqualTo(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332")); + + } + + @Test + public void givenEntity_whenMappingCalendarType_thenTemporalIsSpecifiedExplicitly() throws Exception { + TemporalValues temporalValues = new TemporalValues(); + + Calendar calendarDate = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendarDate.set(Calendar.YEAR, 2017); + calendarDate.set(Calendar.MONTH, 10); + calendarDate.set(Calendar.DAY_OF_MONTH, 15); + temporalValues.setCalendarDate(calendarDate); + + Calendar calendarTimestamp = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + calendarTimestamp.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.322")); + temporalValues.setCalendarTimestamp(calendarTimestamp); + + session.save(temporalValues); + session.flush(); + session.clear(); + + temporalValues = session.get(TemporalValues.class, temporalValues.getId()); + assertThat(temporalValues.getCalendarDate().getTime()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15")); + assertThat(temporalValues.getCalendarTimestamp().getTime()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.322")); + + } + + @Test + public void givenEntity_whenMappingJavaTimeTypes_thenTemporalIsSelectedAutomatically() { + TemporalValues temporalValues = new TemporalValues(); + + temporalValues.setLocalDate(LocalDate.parse("2017-11-15")); + temporalValues.setLocalTime(LocalTime.parse("15:30:18")); + temporalValues.setOffsetTime(OffsetTime.parse("08:22:12+01:00")); + temporalValues.setInstant(Instant.parse("2017-11-15T08:22:12Z")); + temporalValues.setLocalDateTime(LocalDateTime.parse("2017-11-15T08:22:12")); + temporalValues.setOffsetDateTime(OffsetDateTime.parse("2017-11-15T08:22:12+01:00")); + temporalValues.setZonedDateTime(ZonedDateTime.parse("2017-11-15T08:22:12+01:00[Europe/Paris]")); + + session.save(temporalValues); + session.flush(); + session.clear(); + + temporalValues = session.get(TemporalValues.class, temporalValues.getId()); + assertThat(temporalValues.getLocalDate()).isEqualTo(LocalDate.parse("2017-11-15")); + assertThat(temporalValues.getLocalTime()).isEqualTo(LocalTime.parse("15:30:18")); + assertThat(temporalValues.getOffsetTime()).isEqualTo(OffsetTime.parse("08:22:12+01:00")); + assertThat(temporalValues.getInstant()).isEqualTo(Instant.parse("2017-11-15T08:22:12Z")); + assertThat(temporalValues.getLocalDateTime()).isEqualTo(LocalDateTime.parse("2017-11-15T08:22:12")); + assertThat(temporalValues.getOffsetDateTime()).isEqualTo(OffsetDateTime.parse("2017-11-15T08:22:12+01:00")); + assertThat(temporalValues.getZonedDateTime()).isEqualTo(ZonedDateTime.parse("2017-11-15T08:22:12+01:00[Europe/Paris]")); + + } + +} diff --git a/hibernate5/src/test/resources/hibernate-multitenancy.properties b/hibernate5/src/test/resources/hibernate-multitenancy.properties new file mode 100644 index 0000000000..298ecd05d3 --- /dev/null +++ b/hibernate5/src/test/resources/hibernate-multitenancy.properties @@ -0,0 +1,9 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 +hibernate.connection.username=sa +hibernate.connection.autocommit=true +jdbc.password= + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.multiTenancy=DATABASE diff --git a/hibernate5/src/test/resources/hibernate-spatial.properties b/hibernate5/src/test/resources/hibernate-spatial.properties new file mode 100644 index 0000000000..e85cd49cc3 --- /dev/null +++ b/hibernate5/src/test/resources/hibernate-spatial.properties @@ -0,0 +1,10 @@ +hibernate.dialect=org.hibernate.spatial.dialect.mysql.MySQL56SpatialDialect +hibernate.connection.driver_class=com.mysql.jdbc.Driver +hibernate.connection.url=jdbc:mysql://localhost:3306/hibernate-spatial +hibernate.connection.username=root +hibernate.connection.password=pass +hibernate.connection.pool_size=5 +hibernate.show_sql=true +hibernate.format_sql=true +hibernate.max_fetch_depth=5 +hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/hibernate5/src/test/resources/hibernate.properties b/hibernate5/src/test/resources/hibernate.properties index 298ecd05d3..7b8764637b 100644 --- a/hibernate5/src/test/resources/hibernate.properties +++ b/hibernate5/src/test/resources/hibernate.properties @@ -6,4 +6,4 @@ jdbc.password= hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.show_sql=true -hibernate.multiTenancy=DATABASE +hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/httpclient/README.md b/httpclient/README.md index 2a98c2feac..93e0f3c9e1 100644 --- a/httpclient/README.md +++ b/httpclient/README.md @@ -20,3 +20,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [HttpAsyncClient Tutorial](http://www.baeldung.com/httpasyncclient-tutorial) - [HttpClient 4 Tutorial](http://www.baeldung.com/httpclient-guide) - [Advanced HttpClient Configuration](http://www.baeldung.com/httpclient-advanced-config) +- [HttpClient 4 – Do Not Follow Redirects](http://www.baeldung.com/httpclient-stop-follow-redirect) +- [HttpClient 4 – Setting a Custom User-Agent](http://www.baeldung.com/httpclient-user-agent-header) diff --git a/hystrix/pom.xml b/hystrix/pom.xml index 7e9a217dba..58e09816ea 100644 --- a/hystrix/pom.xml +++ b/hystrix/pom.xml @@ -2,7 +2,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - com.baeldung hystrix 1.0 hystrix diff --git a/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutIntegrationTest.java b/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutManualTest.java similarity index 72% rename from hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutIntegrationTest.java rename to hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutManualTest.java index bf0c542980..ed89104c05 100644 --- a/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutIntegrationTest.java +++ b/hystrix/src/test/java/com/baeldung/hystrix/HystrixTimeoutManualTest.java @@ -10,53 +10,53 @@ import org.junit.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -public class HystrixTimeoutIntegrationTest { +public class HystrixTimeoutManualTest { @Test - public void givenInputBobAndDefaultSettings_whenCommandExecuted_thenReturnHelloBob(){ + public void givenInputBobAndDefaultSettings_whenCommandExecuted_thenReturnHelloBob() { assertThat(new CommandHelloWorld("Bob").execute(), equalTo("Hello Bob!")); } @Test public void givenSvcTimeoutOf100AndDefaultSettings_whenRemoteSvcExecuted_thenReturnSuccess() - throws InterruptedException { + throws InterruptedException { HystrixCommand.Setter config = HystrixCommand - .Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroup2")); + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroup2")); assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(100)).execute(), - equalTo("Success")); + equalTo("Success")); } @Test(expected = HystrixRuntimeException.class) public void givenSvcTimeoutOf10000AndDefaultSettings__whenRemoteSvcExecuted_thenExpectHRE() throws InterruptedException { HystrixCommand.Setter config = HystrixCommand - .Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupTest3")); + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupTest3")); new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(10_000)).execute(); } @Test public void givenSvcTimeoutOf5000AndExecTimeoutOf10000_whenRemoteSvcExecuted_thenReturnSuccess() - throws InterruptedException { + throws InterruptedException { HystrixCommand.Setter config = HystrixCommand - .Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupTest4")); + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupTest4")); HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter(); commandProperties.withExecutionTimeoutInMilliseconds(10_000); config.andCommandPropertiesDefaults(commandProperties); assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(), - equalTo("Success")); + equalTo("Success")); } @Test(expected = HystrixRuntimeException.class) public void givenSvcTimeoutOf15000AndExecTimeoutOf5000__whenExecuted_thenExpectHRE() - throws InterruptedException { + throws InterruptedException { HystrixCommand.Setter config = HystrixCommand - .Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupTest5")); + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupTest5")); HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter(); commandProperties.withExecutionTimeoutInMilliseconds(5_000); config.andCommandPropertiesDefaults(commandProperties); @@ -65,45 +65,45 @@ public class HystrixTimeoutIntegrationTest { @Test public void givenSvcTimeoutOf500AndExecTimeoutOf10000AndThreadPool__whenExecuted_thenReturnSuccess() - throws InterruptedException { + throws InterruptedException { HystrixCommand.Setter config = HystrixCommand - .Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupThreadPool")); + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupThreadPool")); HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter(); commandProperties.withExecutionTimeoutInMilliseconds(10_000); config.andCommandPropertiesDefaults(commandProperties); config.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter() - .withMaxQueueSize(10) - .withCoreSize(3) - .withQueueSizeRejectionThreshold(10)); + .withMaxQueueSize(10) + .withCoreSize(3) + .withQueueSizeRejectionThreshold(10)); assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(), - equalTo("Success")); + equalTo("Success")); } @Test public void givenCircuitBreakerSetup__whenRemoteSvcCmdExecuted_thenReturnSuccess() - throws InterruptedException { + throws InterruptedException { HystrixCommand.Setter config = HystrixCommand - .Setter - .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupCircuitBreaker")); + .Setter + .withGroupKey(HystrixCommandGroupKey.Factory.asKey("RemoteServiceGroupCircuitBreaker")); HystrixCommandProperties.Setter properties = HystrixCommandProperties.Setter(); properties.withExecutionTimeoutInMilliseconds(1000); properties.withCircuitBreakerSleepWindowInMilliseconds(4000); properties.withExecutionIsolationStrategy( - HystrixCommandProperties.ExecutionIsolationStrategy.THREAD); + HystrixCommandProperties.ExecutionIsolationStrategy.THREAD); properties.withCircuitBreakerEnabled(true); properties.withCircuitBreakerRequestVolumeThreshold(1); config.andCommandPropertiesDefaults(properties); config.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter() - .withMaxQueueSize(1) - .withCoreSize(1) - .withQueueSizeRejectionThreshold(1)); + .withMaxQueueSize(1) + .withCoreSize(1) + .withQueueSizeRejectionThreshold(1)); assertThat(this.invokeRemoteService(config, 10_000), equalTo(null)); assertThat(this.invokeRemoteService(config, 10_000), equalTo(null)); @@ -111,19 +111,19 @@ public class HystrixTimeoutIntegrationTest { Thread.sleep(5000); assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(), - equalTo("Success")); + equalTo("Success")); assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(), - equalTo("Success")); + equalTo("Success")); assertThat(new RemoteServiceTestCommand(config, new RemoteServiceTestSimulator(500)).execute(), - equalTo("Success")); + equalTo("Success")); } public String invokeRemoteService(HystrixCommand.Setter config, int timeout) - throws InterruptedException { + throws InterruptedException { String response = null; try { response = new RemoteServiceTestCommand(config, - new RemoteServiceTestSimulator(timeout)).execute(); + new RemoteServiceTestSimulator(timeout)).execute(); } catch (HystrixRuntimeException ex) { System.out.println("ex = " + ex); } diff --git a/intelliJ/README.md b/intelliJ/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/intelliJ/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/jackson/README.md b/jackson/README.md index 51919f6769..a05c95de94 100644 --- a/jackson/README.md +++ b/jackson/README.md @@ -28,3 +28,11 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [A Guide to Optional with Jackson](http://www.baeldung.com/jackson-optional) - [Map Serialization and Deserialization with Jackson](http://www.baeldung.com/jackson-map) - [Jackson Streaming API](http://www.baeldung.com/jackson-streaming-api) +- [Jackson – JsonMappingException (No serializer found for class)](http://www.baeldung.com/jackson-jsonmappingexception) +- [How To Serialize Enums as JSON Objects with Jackson](http://www.baeldung.com/jackson-serialize-enums) +- [Jackson – Marshall String to JsonNode](http://www.baeldung.com/jackson-json-to-jsonnode) +- [Ignore Null Fields with Jackson](http://www.baeldung.com/jackson-ignore-null-fields) +- [Jackson – Unmarshall to Collection/Array](http://www.baeldung.com/jackson-collection-array) +- [Jackson – Change Name of Field](http://www.baeldung.com/jackson-name-of-property) +- [Serialize Only Fields that meet a Custom Criteria with Jackson](http://www.baeldung.com/jackson-serialize-field-custom-criteria) +- [Mapping Nested Values with Jackson](http://www.baeldung.com/jackson-nested-values) diff --git a/jackson/pom.xml b/jackson/pom.xml index f970b6a68c..001fde5021 100644 --- a/jackson/pom.xml +++ b/jackson/pom.xml @@ -129,7 +129,7 @@ - 2.9.0 + 2.9.2 19.0 diff --git a/jackson/src/test/java/com/baeldung/jackson/deserialization/nested/DeserializeWithNestedPropertiesUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/deserialization/nested/DeserializeWithNestedPropertiesUnitTest.java new file mode 100644 index 0000000000..037bc7e880 --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/deserialization/nested/DeserializeWithNestedPropertiesUnitTest.java @@ -0,0 +1,70 @@ +package com.baeldung.jackson.deserialization.nested; + +import static org.junit.Assert.*; + +import java.io.IOException; + +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +public class DeserializeWithNestedPropertiesUnitTest { + + private String SOURCE_JSON = "{\"id\":\"957c43f2-fa2e-42f9-bf75-6e3d5bb6960a\",\"name\":\"The Best Product\",\"brand\":{\"id\":\"9bcd817d-0141-42e6-8f04-e5aaab0980b6\",\"name\":\"ACME Products\",\"owner\":{\"id\":\"b21a80b1-0c09-4be3-9ebd-ea3653511c13\",\"name\":\"Ultimate Corp, Inc.\"}}}"; + + @Test + public void whenUsingAnnotations_thenOk() throws IOException { + Product product = new ObjectMapper().readerFor(Product.class) + .readValue(SOURCE_JSON); + + assertEquals(product.getName(), "The Best Product"); + assertEquals(product.getBrandName(), "ACME Products"); + assertEquals(product.getOwnerName(), "Ultimate Corp, Inc."); + } + + @Test + public void whenUsingJsonNode_thenOk() throws IOException { + JsonNode productNode = new ObjectMapper().readTree(SOURCE_JSON); + + Product product = new Product(); + product.setId(productNode.get("id") + .textValue()); + product.setName(productNode.get("name") + .textValue()); + product.setBrandName(productNode.get("brand") + .get("name") + .textValue()); + product.setOwnerName(productNode.get("brand") + .get("owner") + .get("name") + .textValue()); + + assertEquals(product.getName(), "The Best Product"); + assertEquals(product.getBrandName(), "ACME Products"); + assertEquals(product.getOwnerName(), "Ultimate Corp, Inc."); + } + + @Test + public void whenUsingDeserializerManuallyRegistered_thenOk() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + SimpleModule module = new SimpleModule(); + module.addDeserializer(Product.class, new ProductDeserializer()); + mapper.registerModule(module); + + Product product = mapper.readValue(SOURCE_JSON, Product.class); + assertEquals(product.getName(), "The Best Product"); + assertEquals(product.getBrandName(), "ACME Products"); + assertEquals(product.getOwnerName(), "Ultimate Corp, Inc."); + } + + @Test + public void whenUsingDeserializerAutoRegistered_thenOk() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + Product product = mapper.readValue(SOURCE_JSON, Product.class); + assertEquals(product.getName(), "The Best Product"); + assertEquals(product.getBrandName(), "ACME Products"); + assertEquals(product.getOwnerName(), "Ultimate Corp, Inc."); + } +} diff --git a/jackson/src/test/java/com/baeldung/jackson/deserialization/nested/Product.java b/jackson/src/test/java/com/baeldung/jackson/deserialization/nested/Product.java new file mode 100644 index 0000000000..0020afea0f --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/deserialization/nested/Product.java @@ -0,0 +1,55 @@ +package com.baeldung.jackson.deserialization.nested; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonDeserialize(using = ProductDeserializer.class) +public class Product { + + private String id; + private String name; + private String brandName; + private String ownerName; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getBrandName() { + return brandName; + } + + public void setBrandName(String brandName) { + this.brandName = brandName; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + @SuppressWarnings("unchecked") + @JsonProperty("brand") + private void unpackNested(Map brand) { + this.brandName = (String) brand.get("name"); + Map owner = (Map) brand.get("owner"); + this.ownerName = owner.get("name"); + } +} \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/deserialization/nested/ProductDeserializer.java b/jackson/src/test/java/com/baeldung/jackson/deserialization/nested/ProductDeserializer.java new file mode 100644 index 0000000000..daabae6cda --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/deserialization/nested/ProductDeserializer.java @@ -0,0 +1,40 @@ +package com.baeldung.jackson.deserialization.nested; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +@SuppressWarnings("serial") +public class ProductDeserializer extends StdDeserializer { + + public ProductDeserializer() { + this(null); + } + + public ProductDeserializer(Class vc) { + super(vc); + } + + @Override + public Product deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + JsonNode productNode = jp.getCodec() + .readTree(jp); + Product product = new Product(); + product.setId(productNode.get("id") + .textValue()); + product.setName(productNode.get("name") + .textValue()); + product.setBrandName(productNode.get("brand") + .get("name") + .textValue()); + product.setOwnerName(productNode.get("brand") + .get("owner") + .get("name") + .textValue()); + return product; + } +} diff --git a/javaxval/README.md b/javaxval/README.md index b5001789f1..c6a6eb7345 100644 --- a/javaxval/README.md +++ b/javaxval/README.md @@ -7,3 +7,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: - [Java Bean Validation Basics](http://www.baeldung.com/javax-validation) +- [Validating Container Elements with Bean Validation 2.0](http://www.baeldung.com/bean-validation-container-elements) diff --git a/javaxval/pom.xml b/javaxval/pom.xml index 4d27b3e0c9..6a83a25f01 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -6,8 +6,8 @@ 0.1-SNAPSHOT - 1.1.0.Final - 5.3.4.Final + 2.0.0.Final + 6.0.2.Final 3.0.0 2.2.6 diff --git a/javaxval/src/main/java/org/baeldung/Customer.java b/javaxval/src/main/java/org/baeldung/Customer.java new file mode 100644 index 0000000000..a90fb419de --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/Customer.java @@ -0,0 +1,66 @@ +package org.baeldung; + +import java.util.List; +import java.util.Optional; +import java.util.OptionalInt; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.PositiveOrZero; + +public class Customer { + + @NotBlank(message="Name cannot be empty") + private String name; + + private List<@NotBlank(message="Address must not be blank") String> addresses; + + private Integer age; + + @PositiveOrZero + private OptionalInt numberOfOrders; + + //@NotBlank + private Profile profile; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getAddresses() { + return addresses; + } + + public void setAddresses(List addresses) { + this.addresses = addresses; + } + + public Optional<@Min(18) Integer> getAge() { + return Optional.ofNullable(age); + } + + public void setAge(Integer age) { + this.age = age; + } + + public OptionalInt getNumberOfOrders() { + return numberOfOrders; + } + + public void setNumberOfOrders(OptionalInt numberOfOrders) { + this.numberOfOrders = numberOfOrders; + } + + public Profile getProfile() { + return profile; + } + + public void setProfile(Profile profile) { + this.profile = profile; + } + +} diff --git a/javaxval/src/main/java/org/baeldung/CustomerMap.java b/javaxval/src/main/java/org/baeldung/CustomerMap.java new file mode 100644 index 0000000000..37446cf86e --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/CustomerMap.java @@ -0,0 +1,19 @@ +package org.baeldung; + +import java.util.Map; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotNull; + +public class CustomerMap { + + private Map<@Email(message="Must be a valid email") String, @NotNull Customer> customers; + + public Map getCustomers() { + return customers; + } + + public void setCustomers(Map customers) { + this.customers = customers; + } +} diff --git a/javaxval/src/main/java/org/baeldung/Profile.java b/javaxval/src/main/java/org/baeldung/Profile.java new file mode 100644 index 0000000000..ec73a5c62f --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/Profile.java @@ -0,0 +1,13 @@ +package org.baeldung; + +public class Profile { + private String companyName; + + public String getCompanyName() { + return companyName; + } + + public void setCompanyName(String companyName) { + this.companyName = companyName; + } +} diff --git a/javaxval/src/main/java/org/baeldung/User.java b/javaxval/src/main/java/org/baeldung/User.java index 2d86a4ec2f..e2f2732399 100644 --- a/javaxval/src/main/java/org/baeldung/User.java +++ b/javaxval/src/main/java/org/baeldung/User.java @@ -1,56 +1,94 @@ package org.baeldung; +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.Email; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Past; import javax.validation.constraints.Size; +import javax.validation.constraints.NotBlank; public class User { - @NotNull(message = "Name cannot be null") - private String name; + @NotNull(message = "Name cannot be null") + private String name; - @AssertTrue - private boolean working; + @AssertTrue + private boolean working; - @Size(min = 10, max = 200, message = "Number of characters should be in between 10 and 200 inclusive") - private String aboutMe; + @Size(min = 10, max = 200, message = "Number of characters should be in between 10 and 200 inclusive") + private String aboutMe; - @Min(value = 18, message = "Age should not be less than 18") - @Max(value = 150, message = "Age should not be more than 150") - private int age; + @Min(value = 18, message = "Age should not be less than 18") + @Max(value = 150, message = "Age should not be more than 150") + private int age; - public int getAge() { - return age; - } + @Email(message = "Email should be valid") + private String email; + + List<@NotBlank String> preferences; + + private LocalDate dateOfBirth; - public void setAge(int age) { - this.age = age; - } + public int getAge() { + return age; + } - public boolean isWorking() { - return working; - } + public void setAge(int age) { + this.age = age; + } - public void setWorking(boolean working) { - this.working = working; - } + public boolean isWorking() { + return working; + } - public String getAboutMe() { - return aboutMe; - } + public void setWorking(boolean working) { + this.working = working; + } - public void setAboutMe(String aboutMe) { - this.aboutMe = aboutMe; - } + public String getAboutMe() { + return aboutMe; + } - public String getName() { - return name; - } + public void setAboutMe(String aboutMe) { + this.aboutMe = aboutMe; + } - public void setName(String name) { - this.name = name; - } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public Optional<@Past LocalDate> getDateOfBirth() { + return Optional.ofNullable(dateOfBirth); + } + + public void setDateOfBirth(LocalDate dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public List getPreferences() { + return preferences; + } + + public void setPreferences(List preferences) { + this.preferences = preferences; + } + } diff --git a/javaxval/src/main/java/org/baeldung/valueextractors/ProfileValueExtractor.java b/javaxval/src/main/java/org/baeldung/valueextractors/ProfileValueExtractor.java new file mode 100644 index 0000000000..f192034261 --- /dev/null +++ b/javaxval/src/main/java/org/baeldung/valueextractors/ProfileValueExtractor.java @@ -0,0 +1,17 @@ +package org.baeldung.valueextractors; + +import javax.validation.valueextraction.ExtractedValue; +import javax.validation.valueextraction.UnwrapByDefault; +import javax.validation.valueextraction.ValueExtractor; + +import org.baeldung.Profile; + +@UnwrapByDefault +public class ProfileValueExtractor implements ValueExtractor<@ExtractedValue(type = String.class) Profile> { + + @Override + public void extractValues(Profile originalValue, ValueExtractor.ValueReceiver receiver) { + receiver.value(null, originalValue.getCompanyName()); + } + +} diff --git a/javaxval/src/main/resources/META-INF/services/javax.validation.valueextraction.ValueExtractor b/javaxval/src/main/resources/META-INF/services/javax.validation.valueextraction.ValueExtractor new file mode 100644 index 0000000000..e77a30cfe4 --- /dev/null +++ b/javaxval/src/main/resources/META-INF/services/javax.validation.valueextraction.ValueExtractor @@ -0,0 +1 @@ +org.baeldung.valueextractors.ProfileValueExtractor \ No newline at end of file diff --git a/javaxval/src/test/java/org/baeldung/ContainerValidationIntegrationTest.java b/javaxval/src/test/java/org/baeldung/ContainerValidationIntegrationTest.java new file mode 100644 index 0000000000..dff02ff13d --- /dev/null +++ b/javaxval/src/test/java/org/baeldung/ContainerValidationIntegrationTest.java @@ -0,0 +1,88 @@ +package org.baeldung; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; +import java.util.OptionalInt; +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import org.baeldung.valueextractors.ProfileValueExtractor; + +import org.junit.Before; +import org.junit.Test; + +public class ContainerValidationIntegrationTest { + private Validator validator; + + @Before + public void setup() { + ValidatorFactory factory = Validation.byDefaultProvider().configure() + .addValueExtractor(new ProfileValueExtractor()).buildValidatorFactory(); + validator = factory.getValidator(); + } + + @Test + public void whenEmptyAddress_thenValidationFails() { + Customer customer = new Customer(); + customer.setName("John"); + customer.setAddresses(Collections.singletonList(" ")); + Set> violations = validator.validate(customer); + assertEquals(1, violations.size()); + assertEquals("Address must not be blank", violations.iterator() + .next() + .getMessage()); + } + + @Test + public void whenInvalidEmail_thenValidationFails() { + CustomerMap map = new CustomerMap(); + map.setCustomers(Collections.singletonMap("john", new Customer())); + Set> violations = validator.validate(map); + assertEquals(1, violations.size()); + assertEquals("Must be a valid email", violations.iterator() + .next() + .getMessage()); + } + + @Test + public void whenAgeTooLow_thenValidationFails() { + Customer customer = new Customer(); + customer.setName("John"); + customer.setAge(15); + Set> violations = validator.validate(customer); + assertEquals(1, violations.size()); + } + + @Test + public void whenAgeNull_thenValidationSucceeds() { + Customer customer = new Customer(); + customer.setName("John"); + Set> violations = validator.validate(customer); + assertEquals(0, violations.size()); + } + + @Test + public void whenNumberOrdersValid_thenValidationSucceeds() { + Customer customer = new Customer(); + customer.setName("John"); + customer.setNumberOfOrders(OptionalInt.of(1)); + Set> violations = validator.validate(customer); + assertEquals(0, violations.size()); + } + + //@Test + public void whenProfileCompanyNameBlank_thenValidationFails() { + Customer customer = new Customer(); + customer.setName("John"); + Profile profile = new Profile(); + profile.setCompanyName(" "); + customer.setProfile(profile); + Set> violations = validator.validate(customer); + assertEquals(1, violations.size()); + } + +} diff --git a/javaxval/src/test/java/org/baeldung/ValidationIntegrationTest.java b/javaxval/src/test/java/org/baeldung/ValidationIntegrationTest.java index 63c08f64d8..78745a1af2 100644 --- a/javaxval/src/test/java/org/baeldung/ValidationIntegrationTest.java +++ b/javaxval/src/test/java/org/baeldung/ValidationIntegrationTest.java @@ -1,81 +1,126 @@ package org.baeldung; +import java.time.LocalDate; +import java.util.Collections; import java.util.Iterator; import java.util.Set; +import java.util.Optional; + import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; -import org.junit.Assert; +import static org.junit.Assert.*; import org.junit.Test; +import org.junit.Before; public class ValidationIntegrationTest { - @Test - public void ifNameIsNull_nameValidationFails() { - User user = new User(); - user.setWorking(true); - user.setAboutMe("Its all about me!!"); - user.setAge(50); + private Validator validator; - ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); - Validator validator = factory.getValidator(); - Set> violations = validator.validate(user); - Assert.assertEquals(violations.isEmpty(), false); - } + @Before + public void setup() { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + validator = factory.getValidator(); + } - @Test - public void ifSizeNotInRange_aboutMeValidationFails() { - User user = new User(); - user.setName("MyName"); - user.setAboutMe("Its all about me!!"); - user.setAge(50); + private User createUser() { + User user = new User(); + user.setName("John"); + user.setWorking(true); + user.setAge(18); + return user; + } - ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); - Validator validator = factory.getValidator(); - Set> violations = validator.validate(user); - Assert.assertEquals(violations.isEmpty(), false); - } + @Test + public void ifNameIsNull_nameValidationFails() { + User user = new User(); + user.setWorking(true); + user.setAboutMe("Its all about me!!"); + user.setAge(50); + Set> violations = validator.validate(user); + assertEquals(violations.isEmpty(), false); + } - @Test - public void ifWorkingIsFalse_workingValidationFails() { - User user = new User(); - user.setName("MyName"); - user.setAboutMe("Its all about me!!"); - user.setAge(50); + @Test + public void ifSizeNotInRange_aboutMeValidationFails() { + User user = new User(); + user.setName("MyName"); + user.setAboutMe("Its all about me!!"); + user.setAge(50); - ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); - Validator validator = factory.getValidator(); - Set> violations = validator.validate(user); - Assert.assertEquals(violations.isEmpty(), false); - } + Set> violations = validator.validate(user); + assertEquals(violations.isEmpty(), false); + } - @Test - public void ifAgeNotRange_ageValidationFails() { - User user = new User(); - user.setName("MyName"); - user.setAboutMe("Its all about me!!"); - user.setAge(8); + @Test + public void ifWorkingIsFalse_workingValidationFails() { + User user = new User(); + user.setName("MyName"); + user.setAboutMe("Its all about me!!"); + user.setAge(50); - ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); - Validator validator = factory.getValidator(); - Set> violations = validator.validate(user); - Assert.assertEquals(violations.isEmpty(), false); - } - - - @Test - public void ifFnameNullAgeNotRangeAndWorkingIsFalse_validationFailsWithThreeErrors() { - User user = new User(); - user.setAboutMe("Its all about me!!"); - user.setAge(300); + Set> violations = validator.validate(user); + assertEquals(violations.isEmpty(), false); + } - ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); - Validator validator = factory.getValidator(); - Set> violations = validator.validate(user); - Assert.assertEquals(violations.isEmpty(), false); - Assert.assertEquals(violations.size(), 3); - } + @Test + public void ifAgeNotRange_ageValidationFails() { + User user = new User(); + user.setName("MyName"); + user.setAboutMe("Its all about me!!"); + user.setAge(8); + + Set> violations = validator.validate(user); + assertEquals(violations.isEmpty(), false); + } + + @Test + public void ifFnameNullAgeNotRangeAndWorkingIsFalse_validationFailsWithThreeErrors() { + User user = new User(); + user.setAboutMe("Its all about me!!"); + user.setAge(300); + + Set> violations = validator.validate(user); + assertEquals(violations.isEmpty(), false); + assertEquals(violations.size(), 3); + } + + @Test + public void givenInvalidEmail_thenValidationFails() { + User user = createUser(); + user.setEmail("john"); + + Set> violations = validator.validate(user); + assertEquals(1, violations.size()); + } + + @Test + public void givenBlankPreference_thenValidationFails() { + User user = createUser(); + user.setPreferences(Collections.singletonList(" ")); + + Set> violations = validator.validate(user); + assertEquals(1, violations.size()); + } + + @Test + public void givenEmptyOptional_thenValidationSucceeds() { + User user = createUser(); + + Set> violations = validator.validate(user); + assertEquals(0, violations.size()); + } + + @Test + public void givenPastDateOfBirth_thenValidationSuccess() { + User user = createUser(); + user.setDateOfBirth(LocalDate.of(1980, 5, 20)); + + Set> violations = validator.validate(user); + assertEquals(0, violations.size()); + + } } diff --git a/jee7/.gitignore b/jee-7/.gitignore similarity index 100% rename from jee7/.gitignore rename to jee-7/.gitignore diff --git a/jee7/README.md b/jee-7/README.md similarity index 85% rename from jee7/README.md rename to jee-7/README.md index a2493e561b..08a180cfa3 100644 --- a/jee7/README.md +++ b/jee-7/README.md @@ -5,3 +5,4 @@ - [Introduction to JAX-WS](http://www.baeldung.com/jax-ws) - [A Guide to Java EE Web-Related Annotations](http://www.baeldung.com/javaee-web-annotations) - [Introduction to Testing with Arquillian](http://www.baeldung.com/arquillian) +- [Securing Java EE with Spring Security](http://www.baeldung.com/java-ee-spring-security) diff --git a/jee7/pom.xml b/jee-7/pom.xml similarity index 99% rename from jee7/pom.xml rename to jee-7/pom.xml index 6858a05d17..f1d50f55c6 100644 --- a/jee7/pom.xml +++ b/jee-7/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.baeldung - jee7 + jee-7 1.0-SNAPSHOT war JavaEE 7 Arquillian Archetype Sample diff --git a/jee7/src/main/java/com/baeldung/arquillian/CapsConvertor.java b/jee-7/src/main/java/com/baeldung/arquillian/CapsConvertor.java similarity index 100% rename from jee7/src/main/java/com/baeldung/arquillian/CapsConvertor.java rename to jee-7/src/main/java/com/baeldung/arquillian/CapsConvertor.java diff --git a/jee7/src/main/java/com/baeldung/arquillian/CapsService.java b/jee-7/src/main/java/com/baeldung/arquillian/CapsService.java similarity index 100% rename from jee7/src/main/java/com/baeldung/arquillian/CapsService.java rename to jee-7/src/main/java/com/baeldung/arquillian/CapsService.java diff --git a/jee7/src/main/java/com/baeldung/arquillian/Car.java b/jee-7/src/main/java/com/baeldung/arquillian/Car.java similarity index 100% rename from jee7/src/main/java/com/baeldung/arquillian/Car.java rename to jee-7/src/main/java/com/baeldung/arquillian/Car.java diff --git a/jee7/src/main/java/com/baeldung/arquillian/CarEJB.java b/jee-7/src/main/java/com/baeldung/arquillian/CarEJB.java similarity index 100% rename from jee7/src/main/java/com/baeldung/arquillian/CarEJB.java rename to jee-7/src/main/java/com/baeldung/arquillian/CarEJB.java diff --git a/jee7/src/main/java/com/baeldung/arquillian/Component.java b/jee-7/src/main/java/com/baeldung/arquillian/Component.java similarity index 100% rename from jee7/src/main/java/com/baeldung/arquillian/Component.java rename to jee-7/src/main/java/com/baeldung/arquillian/Component.java diff --git a/jee7/src/main/java/com/baeldung/arquillian/ConvertToLowerCase.java b/jee-7/src/main/java/com/baeldung/arquillian/ConvertToLowerCase.java similarity index 100% rename from jee7/src/main/java/com/baeldung/arquillian/ConvertToLowerCase.java rename to jee-7/src/main/java/com/baeldung/arquillian/ConvertToLowerCase.java diff --git a/jee7/src/main/java/com/baeldung/convListVal/ConvListVal.java b/jee-7/src/main/java/com/baeldung/convListVal/ConvListVal.java similarity index 100% rename from jee7/src/main/java/com/baeldung/convListVal/ConvListVal.java rename to jee-7/src/main/java/com/baeldung/convListVal/ConvListVal.java diff --git a/jee7/src/main/java/com/baeldung/convListVal/MyListener.java b/jee-7/src/main/java/com/baeldung/convListVal/MyListener.java similarity index 100% rename from jee7/src/main/java/com/baeldung/convListVal/MyListener.java rename to jee-7/src/main/java/com/baeldung/convListVal/MyListener.java diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/README.txt b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/README.txt similarity index 100% rename from jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/README.txt rename to jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/README.txt diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/pom.xml b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/pom.xml similarity index 100% rename from jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/pom.xml rename to jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/pom.xml diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java similarity index 100% rename from jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java rename to jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/AccountServlet.java diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java similarity index 100% rename from jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java rename to jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/BankAppServletContextListener.java diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/LogInFilter.java b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/LogInFilter.java similarity index 100% rename from jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/LogInFilter.java rename to jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/LogInFilter.java diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java similarity index 100% rename from jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java rename to jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/java/com/baeldung/javaeeannotations/UploadCustomerDocumentsServlet.java diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/WEB-INF/web.xml b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/WEB-INF/web.xml rename to jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/WEB-INF/web.xml diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/index.jsp b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/index.jsp similarity index 100% rename from jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/index.jsp rename to jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/index.jsp diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/login.jsp b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/login.jsp similarity index 100% rename from jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/login.jsp rename to jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/login.jsp diff --git a/jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/upload.jsp b/jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/upload.jsp similarity index 100% rename from jee7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/upload.jsp rename to jee-7/src/main/java/com/baeldung/javaeeannotations/JavaEEAnnotationsSample/src/main/webapp/upload.jsp diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/AddEmployee.java b/jee-7/src/main/java/com/baeldung/jaxws/client/AddEmployee.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/AddEmployee.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/AddEmployee.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/AddEmployeeResponse.java b/jee-7/src/main/java/com/baeldung/jaxws/client/AddEmployeeResponse.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/AddEmployeeResponse.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/AddEmployeeResponse.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/CountEmployees.java b/jee-7/src/main/java/com/baeldung/jaxws/client/CountEmployees.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/CountEmployees.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/CountEmployees.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/CountEmployeesResponse.java b/jee-7/src/main/java/com/baeldung/jaxws/client/CountEmployeesResponse.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/CountEmployeesResponse.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/CountEmployeesResponse.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/DeleteEmployee.java b/jee-7/src/main/java/com/baeldung/jaxws/client/DeleteEmployee.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/DeleteEmployee.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/DeleteEmployee.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/DeleteEmployeeResponse.java b/jee-7/src/main/java/com/baeldung/jaxws/client/DeleteEmployeeResponse.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/DeleteEmployeeResponse.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/DeleteEmployeeResponse.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/Employee.java b/jee-7/src/main/java/com/baeldung/jaxws/client/Employee.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/Employee.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/Employee.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/EmployeeAlreadyExists.java b/jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeAlreadyExists.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/EmployeeAlreadyExists.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeAlreadyExists.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/EmployeeAlreadyExists_Exception.java b/jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeAlreadyExists_Exception.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/EmployeeAlreadyExists_Exception.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeAlreadyExists_Exception.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/EmployeeNotFound.java b/jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeNotFound.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/EmployeeNotFound.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeNotFound.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/EmployeeNotFound_Exception.java b/jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeNotFound_Exception.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/EmployeeNotFound_Exception.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeNotFound_Exception.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/EmployeeService.java b/jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeService.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/EmployeeService.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeService.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/EmployeeServiceClient.java b/jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeServiceClient.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/EmployeeServiceClient.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeServiceClient.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/EmployeeService_Service.java b/jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeService_Service.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/EmployeeService_Service.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/EmployeeService_Service.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/GetAllEmployees.java b/jee-7/src/main/java/com/baeldung/jaxws/client/GetAllEmployees.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/GetAllEmployees.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/GetAllEmployees.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/GetAllEmployeesResponse.java b/jee-7/src/main/java/com/baeldung/jaxws/client/GetAllEmployeesResponse.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/GetAllEmployeesResponse.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/GetAllEmployeesResponse.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/GetEmployee.java b/jee-7/src/main/java/com/baeldung/jaxws/client/GetEmployee.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/GetEmployee.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/GetEmployee.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/GetEmployeeResponse.java b/jee-7/src/main/java/com/baeldung/jaxws/client/GetEmployeeResponse.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/GetEmployeeResponse.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/GetEmployeeResponse.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/ObjectFactory.java b/jee-7/src/main/java/com/baeldung/jaxws/client/ObjectFactory.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/ObjectFactory.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/ObjectFactory.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/UpdateEmployee.java b/jee-7/src/main/java/com/baeldung/jaxws/client/UpdateEmployee.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/UpdateEmployee.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/UpdateEmployee.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/UpdateEmployeeResponse.java b/jee-7/src/main/java/com/baeldung/jaxws/client/UpdateEmployeeResponse.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/UpdateEmployeeResponse.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/UpdateEmployeeResponse.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/client/package-info.java b/jee-7/src/main/java/com/baeldung/jaxws/client/package-info.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/client/package-info.java rename to jee-7/src/main/java/com/baeldung/jaxws/client/package-info.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/bottomup/EmployeeService.java b/jee-7/src/main/java/com/baeldung/jaxws/server/bottomup/EmployeeService.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/bottomup/EmployeeService.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/bottomup/EmployeeService.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/bottomup/EmployeeServiceImpl.java b/jee-7/src/main/java/com/baeldung/jaxws/server/bottomup/EmployeeServiceImpl.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/bottomup/EmployeeServiceImpl.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/bottomup/EmployeeServiceImpl.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/bottomup/exception/EmployeeAlreadyExists.java b/jee-7/src/main/java/com/baeldung/jaxws/server/bottomup/exception/EmployeeAlreadyExists.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/bottomup/exception/EmployeeAlreadyExists.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/bottomup/exception/EmployeeAlreadyExists.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/bottomup/exception/EmployeeNotFound.java b/jee-7/src/main/java/com/baeldung/jaxws/server/bottomup/exception/EmployeeNotFound.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/bottomup/exception/EmployeeNotFound.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/bottomup/exception/EmployeeNotFound.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/bottomup/model/Employee.java b/jee-7/src/main/java/com/baeldung/jaxws/server/bottomup/model/Employee.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/bottomup/model/Employee.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/bottomup/model/Employee.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/config/EmployeeServicePublisher.java b/jee-7/src/main/java/com/baeldung/jaxws/server/config/EmployeeServicePublisher.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/config/EmployeeServicePublisher.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/config/EmployeeServicePublisher.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/repository/EmployeeRepository.java b/jee-7/src/main/java/com/baeldung/jaxws/server/repository/EmployeeRepository.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/repository/EmployeeRepository.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/repository/EmployeeRepository.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/repository/EmployeeRepositoryImpl.java b/jee-7/src/main/java/com/baeldung/jaxws/server/repository/EmployeeRepositoryImpl.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/repository/EmployeeRepositoryImpl.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/repository/EmployeeRepositoryImpl.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDown.java b/jee-7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDown.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDown.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDown.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDownImpl.java b/jee-7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDownImpl.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDownImpl.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDownImpl.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDown_Service.java b/jee-7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDown_Service.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDown_Service.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/topdown/EmployeeServiceTopDown_Service.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/server/topdown/ObjectFactory.java b/jee-7/src/main/java/com/baeldung/jaxws/server/topdown/ObjectFactory.java similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/server/topdown/ObjectFactory.java rename to jee-7/src/main/java/com/baeldung/jaxws/server/topdown/ObjectFactory.java diff --git a/jee7/src/main/java/com/baeldung/jaxws/wsdl/employeeservicetopdown.wsdl b/jee-7/src/main/java/com/baeldung/jaxws/wsdl/employeeservicetopdown.wsdl similarity index 100% rename from jee7/src/main/java/com/baeldung/jaxws/wsdl/employeeservicetopdown.wsdl rename to jee-7/src/main/java/com/baeldung/jaxws/wsdl/employeeservicetopdown.wsdl diff --git a/jee7/src/main/java/com/baeldung/json/Person.java b/jee-7/src/main/java/com/baeldung/json/Person.java similarity index 100% rename from jee7/src/main/java/com/baeldung/json/Person.java rename to jee-7/src/main/java/com/baeldung/json/Person.java diff --git a/jee7/src/main/java/com/baeldung/json/PersonBuilder.java b/jee-7/src/main/java/com/baeldung/json/PersonBuilder.java similarity index 100% rename from jee7/src/main/java/com/baeldung/json/PersonBuilder.java rename to jee-7/src/main/java/com/baeldung/json/PersonBuilder.java diff --git a/jee7/src/main/java/com/baeldung/json/PersonWriter.java b/jee-7/src/main/java/com/baeldung/json/PersonWriter.java similarity index 100% rename from jee7/src/main/java/com/baeldung/json/PersonWriter.java rename to jee-7/src/main/java/com/baeldung/json/PersonWriter.java diff --git a/jee7/src/main/java/com/baeldung/springSecurity/ApplicationConfig.java b/jee-7/src/main/java/com/baeldung/springSecurity/ApplicationConfig.java similarity index 100% rename from jee7/src/main/java/com/baeldung/springSecurity/ApplicationConfig.java rename to jee-7/src/main/java/com/baeldung/springSecurity/ApplicationConfig.java diff --git a/jee7/src/main/java/com/baeldung/springSecurity/SecurityWebApplicationInitializer.java b/jee-7/src/main/java/com/baeldung/springSecurity/SecurityWebApplicationInitializer.java similarity index 100% rename from jee7/src/main/java/com/baeldung/springSecurity/SecurityWebApplicationInitializer.java rename to jee-7/src/main/java/com/baeldung/springSecurity/SecurityWebApplicationInitializer.java diff --git a/jee7/src/main/java/com/baeldung/springSecurity/SpringSecurityConfig.java b/jee-7/src/main/java/com/baeldung/springSecurity/SpringSecurityConfig.java similarity index 100% rename from jee7/src/main/java/com/baeldung/springSecurity/SpringSecurityConfig.java rename to jee-7/src/main/java/com/baeldung/springSecurity/SpringSecurityConfig.java diff --git a/jee7/src/main/java/com/baeldung/springSecurity/controller/HomeController.java b/jee-7/src/main/java/com/baeldung/springSecurity/controller/HomeController.java similarity index 100% rename from jee7/src/main/java/com/baeldung/springSecurity/controller/HomeController.java rename to jee-7/src/main/java/com/baeldung/springSecurity/controller/HomeController.java diff --git a/jee7/src/main/java/com/baeldung/springSecurity/controller/LoginController.java b/jee-7/src/main/java/com/baeldung/springSecurity/controller/LoginController.java similarity index 100% rename from jee7/src/main/java/com/baeldung/springSecurity/controller/LoginController.java rename to jee-7/src/main/java/com/baeldung/springSecurity/controller/LoginController.java diff --git a/jee7/src/main/java/com/baeldung/timer/AutomaticTimerBean.java b/jee-7/src/main/java/com/baeldung/timer/AutomaticTimerBean.java similarity index 100% rename from jee7/src/main/java/com/baeldung/timer/AutomaticTimerBean.java rename to jee-7/src/main/java/com/baeldung/timer/AutomaticTimerBean.java diff --git a/jee7/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java b/jee-7/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java similarity index 100% rename from jee7/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java rename to jee-7/src/main/java/com/baeldung/timer/FixedDelayTimerBean.java diff --git a/jee7/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java b/jee-7/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java similarity index 100% rename from jee7/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java rename to jee-7/src/main/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBean.java diff --git a/jee7/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java b/jee-7/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java similarity index 100% rename from jee7/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java rename to jee-7/src/main/java/com/baeldung/timer/ProgrammaticTimerBean.java diff --git a/jee7/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java b/jee-7/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java similarity index 100% rename from jee7/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java rename to jee-7/src/main/java/com/baeldung/timer/ProgrammaticWithInitialFixedDelayTimerBean.java diff --git a/jee7/src/main/java/com/baeldung/timer/ScheduleTimerBean.java b/jee-7/src/main/java/com/baeldung/timer/ScheduleTimerBean.java similarity index 100% rename from jee7/src/main/java/com/baeldung/timer/ScheduleTimerBean.java rename to jee-7/src/main/java/com/baeldung/timer/ScheduleTimerBean.java diff --git a/jee7/src/main/java/com/baeldung/timer/TimerEvent.java b/jee-7/src/main/java/com/baeldung/timer/TimerEvent.java similarity index 100% rename from jee7/src/main/java/com/baeldung/timer/TimerEvent.java rename to jee-7/src/main/java/com/baeldung/timer/TimerEvent.java diff --git a/jee7/src/main/java/com/baeldung/timer/TimerEventListener.java b/jee-7/src/main/java/com/baeldung/timer/TimerEventListener.java similarity index 100% rename from jee7/src/main/java/com/baeldung/timer/TimerEventListener.java rename to jee-7/src/main/java/com/baeldung/timer/TimerEventListener.java diff --git a/jee7/src/main/java/com/baeldung/timer/WorkerBean.java b/jee-7/src/main/java/com/baeldung/timer/WorkerBean.java similarity index 100% rename from jee7/src/main/java/com/baeldung/timer/WorkerBean.java rename to jee-7/src/main/java/com/baeldung/timer/WorkerBean.java diff --git a/jee7/src/main/resources/META-INF/persistence.xml b/jee-7/src/main/resources/META-INF/persistence.xml similarity index 100% rename from jee7/src/main/resources/META-INF/persistence.xml rename to jee-7/src/main/resources/META-INF/persistence.xml diff --git a/jee7/src/main/webapp/ConvListVal.xhtml b/jee-7/src/main/webapp/ConvListVal.xhtml similarity index 100% rename from jee7/src/main/webapp/ConvListVal.xhtml rename to jee-7/src/main/webapp/ConvListVal.xhtml diff --git a/jee7/src/main/webapp/WEB-INF/beans.xml b/jee-7/src/main/webapp/WEB-INF/beans.xml similarity index 100% rename from jee7/src/main/webapp/WEB-INF/beans.xml rename to jee-7/src/main/webapp/WEB-INF/beans.xml diff --git a/jee7/src/main/webapp/WEB-INF/faces-config.xml b/jee-7/src/main/webapp/WEB-INF/faces-config.xml similarity index 100% rename from jee7/src/main/webapp/WEB-INF/faces-config.xml rename to jee-7/src/main/webapp/WEB-INF/faces-config.xml diff --git a/jee7/src/main/webapp/WEB-INF/spring/security.xml b/jee-7/src/main/webapp/WEB-INF/spring/security.xml similarity index 100% rename from jee7/src/main/webapp/WEB-INF/spring/security.xml rename to jee-7/src/main/webapp/WEB-INF/spring/security.xml diff --git a/jee7/src/main/webapp/WEB-INF/views/admin.jsp b/jee-7/src/main/webapp/WEB-INF/views/admin.jsp similarity index 100% rename from jee7/src/main/webapp/WEB-INF/views/admin.jsp rename to jee-7/src/main/webapp/WEB-INF/views/admin.jsp diff --git a/jee7/src/main/webapp/WEB-INF/views/home.jsp b/jee-7/src/main/webapp/WEB-INF/views/home.jsp similarity index 100% rename from jee7/src/main/webapp/WEB-INF/views/home.jsp rename to jee-7/src/main/webapp/WEB-INF/views/home.jsp diff --git a/jee7/src/main/webapp/WEB-INF/views/login.jsp b/jee-7/src/main/webapp/WEB-INF/views/login.jsp similarity index 100% rename from jee7/src/main/webapp/WEB-INF/views/login.jsp rename to jee-7/src/main/webapp/WEB-INF/views/login.jsp diff --git a/jee7/src/main/webapp/WEB-INF/views/user.jsp b/jee-7/src/main/webapp/WEB-INF/views/user.jsp similarity index 100% rename from jee7/src/main/webapp/WEB-INF/views/user.jsp rename to jee-7/src/main/webapp/WEB-INF/views/user.jsp diff --git a/jee7/src/main/webapp/WEB-INF/web.xml b/jee-7/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from jee7/src/main/webapp/WEB-INF/web.xml rename to jee-7/src/main/webapp/WEB-INF/web.xml diff --git a/jee7/src/main/webapp/index.jsp b/jee-7/src/main/webapp/index.jsp similarity index 100% rename from jee7/src/main/webapp/index.jsp rename to jee-7/src/main/webapp/index.jsp diff --git a/jee7/src/main/webapp/secure.jsp b/jee-7/src/main/webapp/secure.jsp similarity index 100% rename from jee7/src/main/webapp/secure.jsp rename to jee-7/src/main/webapp/secure.jsp diff --git a/jee7/src/test/java/com/baeldug/json/JsonUnitTest.java b/jee-7/src/test/java/com/baeldug/json/JsonUnitTest.java similarity index 100% rename from jee7/src/test/java/com/baeldug/json/JsonUnitTest.java rename to jee-7/src/test/java/com/baeldug/json/JsonUnitTest.java diff --git a/jee7/src/test/java/com/baeldung/arquillan/ArquillianTest.java b/jee-7/src/test/java/com/baeldung/arquillan/ArquillianLiveTest.java similarity index 98% rename from jee7/src/test/java/com/baeldung/arquillan/ArquillianTest.java rename to jee-7/src/test/java/com/baeldung/arquillan/ArquillianLiveTest.java index 5219f221ca..9807162606 100644 --- a/jee7/src/test/java/com/baeldung/arquillan/ArquillianTest.java +++ b/jee-7/src/test/java/com/baeldung/arquillan/ArquillianLiveTest.java @@ -22,7 +22,7 @@ import com.baeldung.arquillian.Component; import com.baeldung.arquillian.ConvertToLowerCase; @RunWith(Arquillian.class) -public class ArquillianTest { +public class ArquillianLiveTest { @Deployment public static JavaArchive createDeployment() { diff --git a/jee7/src/test/java/com/baeldung/convListVal/ConvListValIntegrationTest.java b/jee-7/src/test/java/com/baeldung/convListVal/ConvListValIntegrationTest.java similarity index 100% rename from jee7/src/test/java/com/baeldung/convListVal/ConvListValIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/convListVal/ConvListValIntegrationTest.java diff --git a/jee7/src/test/java/com/baeldung/jaxws/EmployeeServiceLiveTest.java b/jee-7/src/test/java/com/baeldung/jaxws/EmployeeServiceLiveTest.java similarity index 100% rename from jee7/src/test/java/com/baeldung/jaxws/EmployeeServiceLiveTest.java rename to jee-7/src/test/java/com/baeldung/jaxws/EmployeeServiceLiveTest.java diff --git a/jee7/src/test/java/com/baeldung/timer/AutomaticTimerBeanIntegrationTest.java b/jee-7/src/test/java/com/baeldung/timer/AutomaticTimerBeanIntegrationTest.java similarity index 100% rename from jee7/src/test/java/com/baeldung/timer/AutomaticTimerBeanIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/timer/AutomaticTimerBeanIntegrationTest.java diff --git a/jee7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanIntegrationTest.java b/jee-7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanIntegrationTest.java similarity index 100% rename from jee7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/timer/ProgrammaticAtFixedRateTimerBeanIntegrationTest.java diff --git a/jee7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanIntegrationTest.java b/jee-7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanIntegrationTest.java similarity index 100% rename from jee7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/timer/ProgrammaticTimerBeanIntegrationTest.java diff --git a/jee7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanIntegrationTest.java b/jee-7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanIntegrationTest.java similarity index 100% rename from jee7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/timer/ProgrammaticWithFixedDelayTimerBeanIntegrationTest.java diff --git a/jee7/src/test/java/com/baeldung/timer/ScheduleTimerBeanIntegrationTest.java b/jee-7/src/test/java/com/baeldung/timer/ScheduleTimerBeanIntegrationTest.java similarity index 100% rename from jee7/src/test/java/com/baeldung/timer/ScheduleTimerBeanIntegrationTest.java rename to jee-7/src/test/java/com/baeldung/timer/ScheduleTimerBeanIntegrationTest.java diff --git a/jee7/src/test/java/com/baeldung/timer/WithinWindowMatcher.java b/jee-7/src/test/java/com/baeldung/timer/WithinWindowMatcher.java similarity index 100% rename from jee7/src/test/java/com/baeldung/timer/WithinWindowMatcher.java rename to jee-7/src/test/java/com/baeldung/timer/WithinWindowMatcher.java diff --git a/jee7/src/test/resources/META-INF/persistence.xml b/jee-7/src/test/resources/META-INF/persistence.xml similarity index 100% rename from jee7/src/test/resources/META-INF/persistence.xml rename to jee-7/src/test/resources/META-INF/persistence.xml diff --git a/jhipster/README.md b/jhipster/README.md new file mode 100644 index 0000000000..f3655f8ec1 --- /dev/null +++ b/jhipster/README.md @@ -0,0 +1,4 @@ +## Relevant articles: + +- [JHipster with a Microservice Architecture](http://www.baeldung.com/jhipster-microservices) +- [Intro to JHipster](http://www.baeldung.com/jhipster) diff --git a/jjwt/README.md b/jjwt/README.md index 47b51038a8..54a5226056 100644 --- a/jjwt/README.md +++ b/jjwt/README.md @@ -42,4 +42,8 @@ Available commands (assumes httpie - https://github.com/jkbrzt/httpie): Parse passed in JWT enforcing the 'iss' registered claim and the 'hasMotorcycle' custom claim ``` -The Baeldung post that compliments this repo can be found [here](http://www.baeldung.com/) \ No newline at end of file +The Baeldung post that compliments this repo can be found [here](http://www.baeldung.com/) + +## Relevant articles: + +- [Supercharge Java Authentication with JSON Web Tokens (JWTs)](http://www.baeldung.com/java-json-web-tokens-jjwt) diff --git a/jmh/README.md b/jmh/README.md new file mode 100644 index 0000000000..2a2c6a173a --- /dev/null +++ b/jmh/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Microbenchmarking with Java](http://www.baeldung.com/java-microbenchmark-harness) diff --git a/jooby/README.md b/jooby/README.md new file mode 100644 index 0000000000..032e595354 --- /dev/null +++ b/jooby/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Introduction to Jooby Project](http://www.baeldung.com/jooby) diff --git a/json-path/README.md b/json-path/README.md new file mode 100644 index 0000000000..3563dcf880 --- /dev/null +++ b/json-path/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Introduction to JsonPath](http://www.baeldung.com/guide-to-jayway-jsonpath) diff --git a/jsonb/.gitignore b/jsonb/.gitignore new file mode 100644 index 0000000000..dec013dfa4 --- /dev/null +++ b/jsonb/.gitignore @@ -0,0 +1,12 @@ +#folders# +.idea +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/jsonb/README.md b/jsonb/README.md new file mode 100644 index 0000000000..a638f0355c --- /dev/null +++ b/jsonb/README.md @@ -0,0 +1 @@ +## JSON B diff --git a/jsonb/pom.xml b/jsonb/pom.xml new file mode 100644 index 0000000000..5058d89c31 --- /dev/null +++ b/jsonb/pom.xml @@ -0,0 +1,106 @@ + + + 4.0.0 + + com.baeldung + json-b + 0.0.1-SNAPSHOT + jar + + json-b + json-b sample project + + + yasson + + true + + + + + org.eclipse + yasson + ${yasson.version} + + + org.glassfish + javax.json + ${javax.json.version} + + + + + johnzon + + + + org.apache.geronimo.specs + geronimo-json_1.1_spec + ${geronimo-json_1.1_spec.version} + + + org.apache.johnzon + johnzon-jsonb + ${johnzon.version} + + + + + + + javax.json.bind + javax.json.bind-api + ${jsonb-api.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + test + + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + + + + UTF-8 + UTF-8 + 1.8 + 1.8 + 1.0.0 + 5.0.0 + 2.20 + 1.0 + 1.1.3 + 1.0 + 1.0.1 + 1.1.2 + 4.1 + + + \ No newline at end of file diff --git a/jsonb/src/main/java/com/baeldung/adapter/PersonAdapter.java b/jsonb/src/main/java/com/baeldung/adapter/PersonAdapter.java new file mode 100644 index 0000000000..dfab2eb0d2 --- /dev/null +++ b/jsonb/src/main/java/com/baeldung/adapter/PersonAdapter.java @@ -0,0 +1,26 @@ +package com.baeldung.adapter; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.bind.adapter.JsonbAdapter; + +import com.baeldung.jsonb.Person; + +public class PersonAdapter implements JsonbAdapter { + + @Override + public JsonObject adaptToJson(Person p) throws Exception { + return Json.createObjectBuilder() + .add("id", p.getId()) + .add("name", p.getName()) + .build(); + } + + @Override + public Person adaptFromJson(JsonObject adapted) throws Exception { + Person person = new Person(); + person.setId(adapted.getInt("id")); + person.setName(adapted.getString("name")); + return person; + } +} \ No newline at end of file diff --git a/jsonb/src/main/java/com/baeldung/jsonb/Person.java b/jsonb/src/main/java/com/baeldung/jsonb/Person.java new file mode 100644 index 0000000000..a506c1b000 --- /dev/null +++ b/jsonb/src/main/java/com/baeldung/jsonb/Person.java @@ -0,0 +1,127 @@ +package com.baeldung.jsonb; + +import java.math.BigDecimal; +import java.time.LocalDate; + +import javax.json.bind.annotation.JsonbDateFormat; +import javax.json.bind.annotation.JsonbNumberFormat; +import javax.json.bind.annotation.JsonbProperty; +import javax.json.bind.annotation.JsonbTransient; + +public class Person { + + private int id; + @JsonbProperty("person-name") + private String name; + @JsonbProperty(nillable = true) + private String email; + @JsonbTransient + private int age; + @JsonbDateFormat("dd-MM-yyyy") + private LocalDate registeredDate; + private BigDecimal salary; + + public Person() { + this(0, "", "", 0, LocalDate.now(), new BigDecimal(0)); + } + + public Person(int id, String name, String email, int age, LocalDate registeredDate, BigDecimal salary) { + this.id = id; + this.name = name; + this.email = email; + this.age = age; + this.registeredDate = registeredDate; + this.salary = salary; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @JsonbNumberFormat(locale = "en_US", value = "#0.0") + public BigDecimal getSalary() { + return salary; + } + + public void setSalary(BigDecimal salary) { + this.salary = salary; + } + + public LocalDate getRegisteredDate() { + return registeredDate; + } + + public void setRegisteredDate(LocalDate registeredDate) { + this.registeredDate = registeredDate; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Person [id="); + builder.append(id); + builder.append(", name="); + builder.append(name); + builder.append(", email="); + builder.append(email); + builder.append(", age="); + builder.append(age); + builder.append(", registeredDate="); + builder.append(registeredDate); + builder.append(", salary="); + builder.append(salary); + builder.append("]"); + return builder.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + id; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Person other = (Person) obj; + if (id != other.id) + return false; + return true; + } + +} diff --git a/jsonb/src/test/java/com/baeldung/jsonb/JsonbTest.java b/jsonb/src/test/java/com/baeldung/jsonb/JsonbTest.java new file mode 100644 index 0000000000..67beda77e1 --- /dev/null +++ b/jsonb/src/test/java/com/baeldung/jsonb/JsonbTest.java @@ -0,0 +1,188 @@ +package com.baeldung.jsonb; + +import static org.junit.Assert.assertTrue; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.json.bind.Jsonb; +import javax.json.bind.JsonbBuilder; +import javax.json.bind.JsonbConfig; +import javax.json.bind.config.PropertyNamingStrategy; +import javax.json.bind.config.PropertyOrderStrategy; + +import org.apache.commons.collections4.ListUtils; +import org.junit.Test; + +import com.baeldung.adapter.PersonAdapter; + +public class JsonbTest { + + @Test + public void givenPersonList_whenSerializeWithJsonb_thenGetPersonJsonArray() { + Jsonb jsonb = JsonbBuilder.create(); + // @formatter:off + List personList = Arrays.asList( + new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)), + new Person(2, "Jhon", "jhon1@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500)), + new Person(3, "Jhon", null, 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)), + new Person(4, "Tom", "tom@test.com", 21, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500))); + // @formatter:on + String jsonArrayPerson = jsonb.toJson(personList); + // @formatter:off + String jsonExpected = "[" + + "{\"email\":\"jhon@test.com\"," + + "\"id\":1,\"person-name\":\"Jhon\"," + + "\"registeredDate\":\"09-09-2019\"," + + "\"salary\":\"1000.0\"}," + + "{\"email\":\"jhon1@test.com\"," + + "\"id\":2,\"person-name\":\"Jhon\"," + + "\"registeredDate\":\"09-09-2019\"," + + "\"salary\":\"1500.0\"},{\"email\":null," + + "\"id\":3,\"person-name\":\"Jhon\"," + + "\"registeredDate\":\"09-09-2019\"," + + "\"salary\":\"1000.0\"}," + + "{\"email\":\"tom@test.com\"," + + "\"id\":4,\"person-name\":\"Tom\"," + + "\"registeredDate\":\"09-09-2019\"," + + "\"salary\":\"1500.0\"}" + + "]"; + // @formatter:on + assertTrue(jsonArrayPerson.equals(jsonExpected)); + } + + @Test + public void givenPersonJsonArray_whenDeserializeWithJsonb_thenGetPersonList() { + Jsonb jsonb = JsonbBuilder.create(); + // @formatter:off + String personJsonArray = + "[" + + "{\"email\":\"jhon@test.com\"," + + "\"id\":1,\"person-name\":\"Jhon\"," + + "\"registeredDate\":\"09-09-2019\"," + + "\"salary\":\"1000.0\"}," + + "{\"email\":\"jhon1@test.com\"," + + "\"id\":2,\"person-name\":\"Jhon\"," + + "\"registeredDate\":\"09-09-2019\"," + + "\"salary\":\"1500.0\"},{\"email\":null," + + "\"id\":3,\"person-name\":\"Jhon\"," + + "\"registeredDate\":\"09-09-2019\"," + + "\"salary\":\"1000.0\"}," + + "{\"email\":\"tom@test.com\"," + + "\"id\":4,\"person-name\":\"Tom\"," + + "\"registeredDate\":\"09-09-2019\"," + + "\"salary\":\"1500.0\"}" + + "]"; + // @formatter:on + @SuppressWarnings("serial") + List personList = jsonb.fromJson(personJsonArray, new ArrayList() { + }.getClass() + .getGenericSuperclass()); + // @formatter:off + List personListExpected = Arrays.asList( + new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)), + new Person(2, "Jhon", "jhon1@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500)), + new Person(3, "Jhon", null, 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)), + new Person(4, "Tom", "tom@test.com", 21, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500))); + // @formatter:on + assertTrue(ListUtils.isEqualList(personList, personListExpected)); + } + + @Test + public void givenPersonObject_whenNamingStrategy_thenGetCustomPersonJson() { + JsonbConfig config = new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_UNDERSCORES); + Jsonb jsonb = JsonbBuilder.create(config); + Person person = new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000)); + String jsonPerson = jsonb.toJson(person); + // @formatter:off + String jsonExpected = + "{\"email\":\"jhon@test.com\"," + + "\"id\":1," + + "\"person-name\":\"Jhon\"," + + "\"registered_date\":\"07-09-2019\"," + + "\"salary\":\"1000.0\"}"; + // @formatter:on + assertTrue(jsonExpected.equals(jsonPerson)); + } + + @Test + public void givenPersonObject_whenWithPropertyOrderStrategy_thenGetReversePersonJson() { + JsonbConfig config = new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE); + Jsonb jsonb = JsonbBuilder.create(config); + Person person = new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000)); + String jsonPerson = jsonb.toJson(person); + // @formatter:off + String jsonExpected = + "{\"salary\":\"1000.0\","+ + "\"registeredDate\":\"07-09-2019\"," + + "\"person-name\":\"Jhon\"," + + "\"id\":1," + + "\"email\":\"jhon@test.com\"}"; + // @formatter:on + assertTrue(jsonExpected.equals(jsonPerson)); + } + + @Test + public void givenPersonObject_whenSerializeWithJsonb_thenGetPersonJson() { + Jsonb jsonb = JsonbBuilder.create(); + Person person = new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000)); + String jsonPerson = jsonb.toJson(person); + // @formatter:off + String jsonExpected = + "{\"email\":\"jhon@test.com\"," + + "\"id\":1," + + "\"person-name\":\"Jhon\"," + + "\"registeredDate\":\"07-09-2019\"," + + "\"salary\":\"1000.0\"}"; + // @formatter:on + assertTrue(jsonExpected.equals(jsonPerson)); + } + + @Test + public void givenPersonJson_whenDeserializeWithJsonb_thenGetPersonObject() { + Jsonb jsonb = JsonbBuilder.create(); + Person person = new Person(1, "Jhon", "jhon@test.com", 0, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000.0)); + // @formatter:off + String jsonPerson = + "{\"email\":\"jhon@test.com\"," + + "\"id\":1," + + "\"person-name\":\"Jhon\"," + + "\"registeredDate\":\"07-09-2019\"," + + "\"salary\":\"1000.0\"}"; + // @formatter:on + assertTrue(jsonb.fromJson(jsonPerson, Person.class) + .equals(person)); + } + + @Test + public void givenPersonObject_whenSerializeWithAdapter_thenGetPersonJson() { + JsonbConfig config = new JsonbConfig().withAdapters(new PersonAdapter()); + Jsonb jsonb = JsonbBuilder.create(config); + Person person = new Person(1, "Jhon", "jhon@test.com", 0, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000.0));// new Person(1, "Jhon"); + String jsonPerson = jsonb.toJson(person); + // @formatter:off + String jsonExpected = + "{\"id\":1," + + "\"name\":\"Jhon\"}"; + // @formatter:on + assertTrue(jsonExpected.equals(jsonPerson)); + } + + @Test + public void givenPersonJson_whenDeserializeWithAdapter_thenGetPersonObject() { + JsonbConfig config = new JsonbConfig().withAdapters(new PersonAdapter()); + Jsonb jsonb = JsonbBuilder.create(config); + Person person = new Person(1, "Jhon", "jhon@test.com", 0, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000.0));// new Person(1, "Jhon"); + // @formatter:off + String jsonPerson = + "{\"id\":1," + + "\"name\":\"Jhon\"}"; + // @formatter:on + assertTrue(jsonb.fromJson(jsonPerson, Person.class) + .equals(person)); + } + +} diff --git a/junit5/src/main/java/com/baeldung/junit5/DefaultOrderOfExecutionTest.java b/junit5/src/main/java/com/baeldung/junit5/DefaultOrderOfExecutionTest.java new file mode 100644 index 0000000000..15b07ee03a --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/DefaultOrderOfExecutionTest.java @@ -0,0 +1,33 @@ +package com.baeldung.junit5; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.DEFAULT) +public class DefaultOrderOfExecutionTest { + private static StringBuilder output = new StringBuilder(""); + + @Test + public void secondTest() { + output.append("b"); + } + + @Test + public void thirdTest() { + output.append("c"); + } + + @Test + public void firstTest() { + output.append("a"); + } + + @AfterClass + public static void assertOutput() { + assertEquals(output.toString(), "cab"); + } +} diff --git a/junit5/src/main/java/com/baeldung/junit5/JVMOrderOfExecutionTest.java b/junit5/src/main/java/com/baeldung/junit5/JVMOrderOfExecutionTest.java new file mode 100644 index 0000000000..189efc8945 --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/JVMOrderOfExecutionTest.java @@ -0,0 +1,26 @@ +package com.baeldung.junit5; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.JVM) +public class JVMOrderOfExecutionTest { + + private static StringBuilder output = new StringBuilder(""); + + @Test + public void secondTest() { + output.append("b"); + } + + @Test + public void thirdTest() { + output.append("c"); + } + + @Test + public void firstTest() { + output.append("a"); + } +} \ No newline at end of file diff --git a/junit5/src/main/java/com/baeldung/junit5/NameAscendingOrderOfExecutionTest.java b/junit5/src/main/java/com/baeldung/junit5/NameAscendingOrderOfExecutionTest.java new file mode 100644 index 0000000000..88de057fc8 --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/NameAscendingOrderOfExecutionTest.java @@ -0,0 +1,33 @@ +package com.baeldung.junit5; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class NameAscendingOrderOfExecutionTest { + private static StringBuilder output = new StringBuilder(""); + + @Test + public void secondTest() { + output.append("b"); + } + + @Test + public void thirdTest() { + output.append("c"); + } + + @Test + public void firstTest() { + output.append("a"); + } + + @AfterClass + public static void assertOutput() { + assertEquals(output.toString(), "abc"); + } +} diff --git a/libraries-data/README.md b/libraries-data/README.md new file mode 100644 index 0000000000..ceb0a1d5f7 --- /dev/null +++ b/libraries-data/README.md @@ -0,0 +1,4 @@ +### Relevant articles +- [Introduction to Reladomo](http://www.baeldung.com/reladomo) +- [Introduction to ORMLite](http://www.baeldung.com/ormlite) +- [Introduction To Kryo](http://www.baeldung.com/kryo) diff --git a/libraries-data/file.dat b/libraries-data/file.dat new file mode 100644 index 0000000000..70177cef97 Binary files /dev/null and b/libraries-data/file.dat differ diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index cae8a725a6..90b1f6bb1d 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -36,6 +36,11 @@ reladomo-test-util ${reladomo.version}
    + + com.j256.ormlite + ormlite-jdbc + ${ormlite.version} + @@ -144,5 +149,6 @@ 16.5.1 4.12 3.6.2 + 5.0 \ No newline at end of file diff --git a/libraries-data/src/main/java/com/baeldung/ormlite/Address.java b/libraries-data/src/main/java/com/baeldung/ormlite/Address.java new file mode 100644 index 0000000000..747b0b0b12 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/ormlite/Address.java @@ -0,0 +1,37 @@ +package com.baeldung.ormlite; + +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +@DatabaseTable(tableName = "addresses") +public class Address { + @DatabaseField(generatedId = true) + private long addressId; + + @DatabaseField(canBeNull = false) + private String addressLine; + + public Address() { + } + + public Address(String addressLine) { + this.addressLine = addressLine; + } + + public long getAddressId() { + return addressId; + } + + public void setAddressId(long addressId) { + this.addressId = addressId; + } + + public String getAddressLine() { + return addressLine; + } + + public void setAddressLine(String addressLine) { + this.addressLine = addressLine; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/ormlite/Book.java b/libraries-data/src/main/java/com/baeldung/ormlite/Book.java new file mode 100644 index 0000000000..ed7b813b8d --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/ormlite/Book.java @@ -0,0 +1,49 @@ +package com.baeldung.ormlite; + +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +@DatabaseTable +public class Book { + + @DatabaseField(generatedId = true) + private long bookId; + + @DatabaseField + private String title; + + @DatabaseField(foreign = true, foreignAutoRefresh = true, foreignAutoCreate = true) + private Library library; + + public Book() { + } + + public Book(String title) { + this.title = title; + } + + public long getBookId() { + return bookId; + } + + public void setBookId(long bookId) { + this.bookId = bookId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Library getLibrary() { + return library; + } + + public void setLibrary(Library library) { + this.library = library; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/ormlite/Library.java b/libraries-data/src/main/java/com/baeldung/ormlite/Library.java new file mode 100644 index 0000000000..994b4c6575 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/ormlite/Library.java @@ -0,0 +1,58 @@ +package com.baeldung.ormlite; + +import com.j256.ormlite.dao.ForeignCollection; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.field.ForeignCollectionField; +import com.j256.ormlite.table.DatabaseTable; + +@DatabaseTable(tableName = "libraries", daoClass = LibraryDaoImpl.class) +public class Library { + + @DatabaseField(generatedId = true) + private long libraryId; + + @DatabaseField(canBeNull = false) + private String name; + + @DatabaseField(foreign = true, foreignAutoCreate = true, foreignAutoRefresh = true) + private Address address; + + @ForeignCollectionField(eager = false) + private ForeignCollection books; + + public Library() { + } + + public long getLibraryId() { + return libraryId; + } + + public void setLibraryId(long libraryId) { + this.libraryId = libraryId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public ForeignCollection getBooks() { + return books; + } + + public void setBooks(ForeignCollection books) { + this.books = books; + } + +} diff --git a/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDao.java b/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDao.java new file mode 100644 index 0000000000..fd8f5f40d6 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDao.java @@ -0,0 +1,10 @@ +package com.baeldung.ormlite; + +import java.sql.SQLException; +import java.util.List; + +import com.j256.ormlite.dao.Dao; + +public interface LibraryDao extends Dao { + public List findByName(String name) throws SQLException; +} diff --git a/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDaoImpl.java b/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDaoImpl.java new file mode 100644 index 0000000000..af313101e2 --- /dev/null +++ b/libraries-data/src/main/java/com/baeldung/ormlite/LibraryDaoImpl.java @@ -0,0 +1,21 @@ +package com.baeldung.ormlite; + +import java.sql.SQLException; +import java.util.List; + +import com.j256.ormlite.dao.BaseDaoImpl; +import com.j256.ormlite.support.ConnectionSource; + +public class LibraryDaoImpl extends BaseDaoImpl implements LibraryDao { + + public LibraryDaoImpl(ConnectionSource connectionSource) throws SQLException { + super(connectionSource, Library.class); + } + + @Override + public List findByName(String name) throws SQLException { + return super.queryForEq("name", name); + + } + +} diff --git a/libraries-data/src/test/java/com/baeldung/ormlite/ORMLiteIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/ormlite/ORMLiteIntegrationTest.java new file mode 100644 index 0000000000..5a713902b4 --- /dev/null +++ b/libraries-data/src/test/java/com/baeldung/ormlite/ORMLiteIntegrationTest.java @@ -0,0 +1,168 @@ +package com.baeldung.ormlite; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import com.j256.ormlite.dao.CloseableWrappedIterable; +import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.dao.DaoManager; +import com.j256.ormlite.jdbc.JdbcPooledConnectionSource; +import com.j256.ormlite.table.TableUtils; + +public class ORMLiteIntegrationTest { + private static JdbcPooledConnectionSource connectionSource; + + private static Dao libraryDao; + private static Dao bookDao; + + @BeforeClass + public static void setup() throws SQLException { + connectionSource = new JdbcPooledConnectionSource("jdbc:h2:mem:myDb"); + TableUtils.createTableIfNotExists(connectionSource, Library.class); + TableUtils.createTableIfNotExists(connectionSource, Address.class); + TableUtils.createTableIfNotExists(connectionSource, Book.class); + + libraryDao = DaoManager.createDao(connectionSource, Library.class); + + bookDao = DaoManager.createDao(connectionSource, Book.class); + } + + @Test + public void givenDAO_whenCRUD_thenOk() throws SQLException { + Library library = new Library(); + library.setName("My Library"); + libraryDao.create(library); + + Library result = libraryDao.queryForId(library.getLibraryId()); + assertEquals("My Library", result.getName()); + + library.setName("My Other Library"); + libraryDao.update(library); + + libraryDao.delete(library); + + } + + @Test + public void whenLoopDao_thenOk() throws SQLException { + Library library1 = new Library(); + library1.setName("My Library"); + libraryDao.create(library1); + + Library library2 = new Library(); + library2.setName("My Other Library"); + libraryDao.create(library2); + + libraryDao.forEach(lib -> { + System.out.println(lib.getName()); + }); + + } + + @Test + public void givenIterator_whenLoop_thenOk() throws SQLException, IOException { + Library library1 = new Library(); + library1.setName("My Library"); + libraryDao.create(library1); + + Library library2 = new Library(); + library2.setName("My Other Library"); + libraryDao.create(library2); + + try (CloseableWrappedIterable wrappedIterable = libraryDao.getWrappedIterable()) { + wrappedIterable.forEach(lib -> { + System.out.println(lib.getName()); + }); + } + + } + + @Test + public void givenCustomDao_whenSave_thenOk() throws SQLException, IOException { + Library library = new Library(); + library.setName("My Library"); + + LibraryDao customLibraryDao = DaoManager.createDao(connectionSource, Library.class); + customLibraryDao.create(library); + assertEquals(1, customLibraryDao.findByName("My Library") + .size()); + } + + @Test + public void whenSaveForeignField_thenOk() throws SQLException, IOException { + Library library = new Library(); + library.setName("My Library"); + library.setAddress(new Address("Main Street nr 20")); + libraryDao.create(library); + + Dao addressDao = DaoManager.createDao(connectionSource, Address.class); + assertEquals(1, addressDao.queryForEq("addressLine", "Main Street nr 20") + .size()); + } + + @Test + public void whenSaveForeignCollection_thenOk() throws SQLException, IOException { + Library library = new Library(); + library.setName("My Library"); + libraryDao.create(library); + libraryDao.refresh(library); + library.getBooks() + .add(new Book("1984")); + + Book book = new Book("It"); + book.setLibrary(library); + bookDao.create(book); + + assertEquals(2, bookDao.queryForEq("library_id", library) + .size()); + } + + @Test + public void whenGetLibrariesWithMoreThanOneBook_thenOk() throws SQLException, IOException { + Library library = new Library(); + library.setName("My Library"); + libraryDao.create(library); + Library library2 = new Library(); + library2.setName("My Other Library"); + libraryDao.create(library2); + + libraryDao.refresh(library); + libraryDao.refresh(library2); + + library.getBooks() + .add(new Book("Book1")); + library2.getBooks() + .add(new Book("Book2")); + library2.getBooks() + .add(new Book("Book3")); + + List libraries = libraryDao.queryBuilder() + .where() + .in("libraryId", bookDao.queryBuilder() + .selectColumns("library_id") + .groupBy("library_id") + .having("count(*) > 1")) + .query(); + assertEquals(1, libraries.size()); + + } + + @After + public void clear() throws SQLException { + TableUtils.clearTable(connectionSource, Library.class); + TableUtils.clearTable(connectionSource, Book.class); + TableUtils.clearTable(connectionSource, Address.class); + } + + @AfterClass + public static void tearDown() throws SQLException, IOException { + connectionSource.close(); + } +} diff --git a/libraries-data/src/test/java/com/baeldung/reladomo/ReladomoTest.java b/libraries-data/src/test/java/com/baeldung/reladomo/ReladomoIntegrationTest.java similarity index 96% rename from libraries-data/src/test/java/com/baeldung/reladomo/ReladomoTest.java rename to libraries-data/src/test/java/com/baeldung/reladomo/ReladomoIntegrationTest.java index 61c29e8aa3..3660d9a8e1 100644 --- a/libraries-data/src/test/java/com/baeldung/reladomo/ReladomoTest.java +++ b/libraries-data/src/test/java/com/baeldung/reladomo/ReladomoIntegrationTest.java @@ -9,7 +9,7 @@ import org.junit.Test; import com.gs.fw.common.mithra.test.ConnectionManagerForTests; import com.gs.fw.common.mithra.test.MithraTestResource; -public class ReladomoTest { +public class ReladomoIntegrationTest { private MithraTestResource mithraTestResource; @Before diff --git a/libraries/README.md b/libraries/README.md index ed6d214c7a..ae2522ca9e 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -8,9 +8,9 @@ - [Embedded Jetty Server in Java](http://www.baeldung.com/jetty-embedded) - [Introduction to Apache Flink with Java](http://www.baeldung.com/apache-flink) - [Introduction to JSONassert](http://www.baeldung.com/jsonassert) -- [Intro to JaVer](http://www.baeldung.com/javers) +- [Intro to JaVers](http://www.baeldung.com/javers) - [Introduction to Apache Commons Math](http://www.baeldung.com/apache-commons-math) -- [Intro to JaVer](http://www.baeldung.com/serenity-bdd) +- [Intro to Serenity BDD](http://www.baeldung.com/serenity-bdd) - [Introduction to Netty](http://www.baeldung.com/netty) - [Merging Streams in Java](http://www.baeldung.com/java-merge-streams) - [Serenity BDD and Screenplay](http://www.baeldung.com/serenity-screenplay) @@ -27,10 +27,37 @@ - [A Guide to Apache Commons DbUtils](http://www.baeldung.com/apache-commons-dbutils) - [Introduction to Awaitility](http://www.baeldung.com/awaitlity-testing) - [Guide to the HyperLogLog Algorithm](http://www.baeldung.com/java-hyperloglog) -- [Introduction to Neuroph](http://www.baeldung.com/intro-to-neuroph) +- [Introduction to Neuroph](http://www.baeldung.com/neuroph) - [Guide to Apache Commons CircularFifoQueue](http://www.baeldung.com/commons-circular-fifo-queue) - [Quick Guide to RSS with Rome](http://www.baeldung.com/rome-rss) - [Introduction to NoException](http://www.baeldung.com/intrduction-to-noexception) +- [Introduction to PCollections](http://www.baeldung.com/java-pcollections) +- [Introduction to Hoverfly in Java](http://www.baeldung.com/hoverfly) +- [Apache Commons Chain](http://www.baeldung.com/apache-commons-chain) +- [Introduction to Eclipse Collections](http://www.baeldung.com/eclipse-collections) +- [DistinctBy in Java Stream API](http://www.baeldung.com/java-streams-distinct-by) +- [Introduction to Apache Commons CSV](http://www.baeldung.com/apache-commons-csv) +- [Difference Between Two Dates in Java](http://www.baeldung.com/java-date-difference) +- [Introduction to NoException](http://www.baeldung.com/no-exception) +- [Apache Commons IO](http://www.baeldung.com/apache-commons-io) +- [Introduction to Conflict-Free Replicated Data Types](http://www.baeldung.com/java-conflict-free-replicated-data-types) +- [Introduction to javax.measure](http://www.baeldung.com/javax-measure) +- [Spring Yarg Integration](http://www.baeldung.com/spring-yarg) +- [Delete a Directory Recursively in Java](http://www.baeldung.com/java-delete-directory) +- [Guide to JDeferred](http://www.baeldung.com/jdeferred) +- [Integrating Retrofit with RxJava](http://www.baeldung.com/retrofit-rxjava) +- [Introduction to MBassador](http://www.baeldung.com/mbassador) +- [Introduction to JCache](http://www.baeldung.com/jcache) +- [Introduction to Retrofit](http://www.baeldung.com/retrofit) +- [Using Pairs in Java](http://www.baeldung.com/java-pairs) +- [Apache Commons Collections Bag](http://www.baeldung.com/apache-commons-bag) +- [Introduction to Caffeine](http://www.baeldung.com/java-caching-caffeine) +- [Introduction to Chronicle Queue](http://www.baeldung.com/java-chronicle-queue) +- [Introduction To Docx4J](http://www.baeldung.com/docx4j) +- [Introduction to StreamEx](http://www.baeldung.com/streamex) +- [Introduction to BouncyCastle with Java](http://www.baeldung.com/java-bouncy-castle) +- [Intro to JDO Queries 2/2](http://www.baeldung.com/jdo-queries) +- [Guide to google-http-client](http://www.baeldung.com/google-http-client) The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own. diff --git a/libraries/helloWorld.docx b/libraries/helloWorld.docx new file mode 100644 index 0000000000..09e71a4d4e Binary files /dev/null and b/libraries/helloWorld.docx differ diff --git a/libraries/pom.xml b/libraries/pom.xml index 6666900c1d..27d867b68b 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -105,6 +105,13 @@ + + maven-compiler-plugin + + 1.8 + 1.8 + + @@ -136,11 +143,11 @@ ${commons-text.version} - javax.measure - jsr-275 - 1.0.0 + tec.units + unit-ri + 1.0.3 - + org.apache.commons commons-collections4 ${commons.collections.version} @@ -326,6 +333,11 @@ datanucleus-xml 5.0.0-release + + org.datanucleus + datanucleus-jdo-query + 5.0.2 + net.openhft chronicle @@ -487,21 +499,7 @@ vavr ${vavr.version} - - org.geotools - gt-shapefile - ${geotools.version} - - - org.geotools - gt-epsg-hsql - ${geotools.version} - - - org.geotools - gt-swing - ${geotools.version} - + com.squareup.retrofit2 @@ -518,6 +516,11 @@ adapter-rxjava ${retrofit.version} + + com.squareup.okhttp3 + logging-interceptor + 3.9.0 + com.darwinsys hirondelle-date4j @@ -554,6 +557,86 @@ protonpack ${protonpack.version} + + org.functionaljava + functionaljava + 4.7 + + + org.functionaljava + functionaljava-java8 + 4.7 + + + org.functionaljava + functionaljava-quickcheck + 4.7 + + + org.functionaljava + functionaljava-java-core + 4.7 + + + javax.cache + cache-api + ${cache.version} + + + com.hazelcast + hazelcast + ${hazelcast.version} + + + org.jgrapht + jgrapht-core + 1.0.1 + + + com.netopyr.wurmloch + wurmloch-crdt + ${crdt.version} + + + org.docx4j + docx4j + 3.3.5 + + + javax.xml.bind + jaxb-api + 2.1 + + + com.github.ben-manes.caffeine + caffeine + ${caffeine.version} + + + org.bouncycastle + bcprov-jdk15on + 1.58 + + + org.bouncycastle + bcpkix-jdk15on + 1.58 + + + com.google.http-client + google-http-client + ${googleclient.version} + + + com.google.http-client + google-http-client-jackson2 + ${googleclient.version} + + + com.google.http-client + google-http-client-gson + ${googleclient.version} + @@ -561,19 +644,6 @@ Java.net repository http://download.java.net/maven/2 - - osgeo - Open Source Geospatial Foundation Repository - http://download.osgeo.org/webdav/geotools/ - - - - true - - opengeo - OpenGeo Maven Repository - http://repo.opengeo.org - false @@ -584,6 +654,8 @@ + 1.23.0 + 0.1.0 0.7.0 3.2.4 3.6 @@ -628,9 +700,15 @@ 0.6.5 0.9.0 15.2 + 2.9.9 + 1.5.1 2.3.0 2.9.9 1.5.1 - 1.14 + 1.14 + 1.0.3 + 1.0.0 + 3.8.4 + 2.5.5 - + \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java b/libraries/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java new file mode 100644 index 0000000000..5d8a7a6643 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java @@ -0,0 +1,111 @@ +package com.baeldung.bouncycastle; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.PrivateKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.cms.ContentInfo; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaCertStore; +import org.bouncycastle.cms.CMSAlgorithm; +import org.bouncycastle.cms.CMSEnvelopedData; +import org.bouncycastle.cms.CMSEnvelopedDataGenerator; +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSProcessableByteArray; +import org.bouncycastle.cms.CMSSignedData; +import org.bouncycastle.cms.CMSSignedDataGenerator; +import org.bouncycastle.cms.CMSTypedData; +import org.bouncycastle.cms.KeyTransRecipientInformation; +import org.bouncycastle.cms.RecipientInformation; +import org.bouncycastle.cms.SignerInformation; +import org.bouncycastle.cms.SignerInformationStore; +import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; +import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; +import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; +import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipient; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.OutputEncryptor; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; +import org.bouncycastle.util.Store; + +public class BouncyCastleCrypto { + + public static byte[] signData(byte[] data, final X509Certificate signingCertificate, final PrivateKey signingKey) + throws CertificateEncodingException, OperatorCreationException, CMSException, IOException { + byte[] signedMessage = null; + List certList = new ArrayList(); + CMSTypedData cmsData = new CMSProcessableByteArray(data); + certList.add(signingCertificate); + Store certs = new JcaCertStore(certList); + CMSSignedDataGenerator cmsGenerator = new CMSSignedDataGenerator(); + ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withRSA").build(signingKey); + cmsGenerator.addSignerInfoGenerator( + new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) + .build(contentSigner, signingCertificate)); + cmsGenerator.addCertificates(certs); + CMSSignedData cms = cmsGenerator.generate(cmsData, true); + signedMessage = cms.getEncoded(); + return signedMessage; + } + + public static boolean verifSignData(final byte[] signedData) + throws CMSException, IOException, OperatorCreationException, CertificateException { + ByteArrayInputStream bIn = new ByteArrayInputStream(signedData); + ASN1InputStream aIn = new ASN1InputStream(bIn); + CMSSignedData s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); + aIn.close(); + bIn.close(); + Store certs = s.getCertificates(); + SignerInformationStore signers = s.getSignerInfos(); + Collection c = signers.getSigners(); + SignerInformation signer = c.iterator().next(); + Collection certCollection = certs.getMatches(signer.getSID()); + Iterator certIt = certCollection.iterator(); + X509CertificateHolder certHolder = certIt.next(); + boolean verifResult = signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(certHolder)); + if (!verifResult) { + return false; + } + return true; + } + + public static byte[] encryptData(final byte[] data, X509Certificate encryptionCertificate) + throws CertificateEncodingException, CMSException, IOException { + byte[] encryptedData = null; + if (null != data && null != encryptionCertificate) { + CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator = new CMSEnvelopedDataGenerator(); + JceKeyTransRecipientInfoGenerator jceKey = new JceKeyTransRecipientInfoGenerator(encryptionCertificate); + cmsEnvelopedDataGenerator.addRecipientInfoGenerator(jceKey); + CMSTypedData msg = new CMSProcessableByteArray(data); + OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC") + .build(); + CMSEnvelopedData cmsEnvelopedData = cmsEnvelopedDataGenerator.generate(msg, encryptor); + encryptedData = cmsEnvelopedData.getEncoded(); + } + return encryptedData; + } + + public static byte[] decryptData(final byte[] encryptedData, final PrivateKey decryptionKey) throws CMSException { + byte[] decryptedData = null; + if (null != encryptedData && null != decryptionKey) { + CMSEnvelopedData envelopedData = new CMSEnvelopedData(encryptedData); + Collection recip = envelopedData.getRecipientInfos().getRecipients(); + KeyTransRecipientInformation recipientInfo = (KeyTransRecipientInformation) recip.iterator().next(); + JceKeyTransRecipient recipient = new JceKeyTransEnvelopedRecipient(decryptionKey); + decryptedData = recipientInfo.getContent(recipient); + } + return decryptedData; + } +} diff --git a/libraries/src/main/java/com/baeldung/caffeine/DataObject.java b/libraries/src/main/java/com/baeldung/caffeine/DataObject.java new file mode 100644 index 0000000000..a90b3e9f21 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/caffeine/DataObject.java @@ -0,0 +1,32 @@ +package com.baeldung.caffeine; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class DataObject { + private final String data; + + private static int objectCounter = 0; + private static final Logger log = LoggerFactory.getLogger(DataObject.class); + + private DataObject(String data) { + this.data = data; + } + + public String getData() { + return data; + } + + @Override + public String toString() { + return "DataObject{" + + "data='" + data + '\'' + + '}'; + } + + public static DataObject get(String data) { + objectCounter++; + log.info("Init DataObject#{} with '{}'", objectCounter, data); + return new DataObject(data); + } +} diff --git a/libraries/src/main/java/com/baeldung/commons/io/FileMonitor.java b/libraries/src/main/java/com/baeldung/commons/io/FileMonitor.java new file mode 100644 index 0000000000..d42323a5df --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/io/FileMonitor.java @@ -0,0 +1,43 @@ +package com.baeldung.commons.io; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.monitor.FileAlterationListener; +import org.apache.commons.io.monitor.FileAlterationListenerAdaptor; +import org.apache.commons.io.monitor.FileAlterationMonitor; +import org.apache.commons.io.monitor.FileAlterationObserver; + +import java.io.File; + +public class FileMonitor { + + public static void main(String[] args) throws Exception { + File folder = FileUtils.getTempDirectory(); + startFileMonitor(folder); + } + + /** + * @param folder + * @throws Exception + */ + public static void startFileMonitor(File folder) throws Exception { + FileAlterationObserver observer = new FileAlterationObserver(folder); + FileAlterationMonitor monitor = new FileAlterationMonitor(5000); + + FileAlterationListener fal = new FileAlterationListenerAdaptor() { + + @Override + public void onFileCreate(File file) { + // on create action + } + + @Override + public void onFileDelete(File file) { + // on delete action + } + }; + + observer.addListener(fal); + monitor.addObserver(observer); + monitor.start(); + } +} \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/BuilderMethods.java b/libraries/src/main/java/com/baeldung/commons/lang3/BuilderMethods.java index c64f7e7511..35cae7426d 100644 --- a/libraries/src/main/java/com/baeldung/commons/lang3/BuilderMethods.java +++ b/libraries/src/main/java/com/baeldung/commons/lang3/BuilderMethods.java @@ -3,6 +3,8 @@ package com.baeldung.commons.lang3; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.concurrent.ConcurrentException; +import org.apache.commons.lang3.concurrent.BackgroundInitializer; public class BuilderMethods { @@ -56,5 +58,36 @@ public class BuilderMethods { System.out.println(simple1.getName()); System.out.println(simple1.hashCode()); System.out.println(simple1.toString()); + + SampleLazyInitializer sampleLazyInitializer = new SampleLazyInitializer(); + + try { + sampleLazyInitializer.get(); + } catch (ConcurrentException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + SampleBackgroundInitializer sampleBackgroundInitializer = new SampleBackgroundInitializer(); + sampleBackgroundInitializer.start(); + + // Proceed with other tasks instead of waiting for the SampleBackgroundInitializer task to finish. + + try { + Object result = sampleBackgroundInitializer.get(); + } catch (ConcurrentException e) { + e.printStackTrace(); + } } } + +class SampleBackgroundInitializer extends BackgroundInitializer{ + + @Override + protected String initialize() throws Exception { + return null; + } + + // Any complex task that takes some time + +} diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/SampleLazyInitializer.java b/libraries/src/main/java/com/baeldung/commons/lang3/SampleLazyInitializer.java new file mode 100644 index 0000000000..56a49d2659 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/lang3/SampleLazyInitializer.java @@ -0,0 +1,11 @@ +package com.baeldung.commons.lang3; + +import org.apache.commons.lang3.concurrent.LazyInitializer; + +public class SampleLazyInitializer extends LazyInitializer { + + @Override + protected SampleObject initialize() { + return new SampleObject(); + } +} \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/SampleObject.java b/libraries/src/main/java/com/baeldung/commons/lang3/SampleObject.java new file mode 100644 index 0000000000..0e61176732 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/lang3/SampleObject.java @@ -0,0 +1,7 @@ +package com.baeldung.commons.lang3; + +public class SampleObject { + + //Ignored + +} diff --git a/libraries/src/main/java/com/baeldung/docx/Docx4jExample.java b/libraries/src/main/java/com/baeldung/docx/Docx4jExample.java new file mode 100644 index 0000000000..d9c87b3889 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/docx/Docx4jExample.java @@ -0,0 +1,109 @@ +package com.baeldung.docx; + +import org.docx4j.dml.wordprocessingDrawing.Inline; +import org.docx4j.jaxb.Context; +import org.docx4j.model.table.TblFactory; +import org.docx4j.openpackaging.exceptions.Docx4JException; +import org.docx4j.openpackaging.packages.WordprocessingMLPackage; +import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage; +import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; +import org.docx4j.wml.BooleanDefaultTrue; +import org.docx4j.wml.Color; +import org.docx4j.wml.Drawing; +import org.docx4j.wml.ObjectFactory; +import org.docx4j.wml.P; +import org.docx4j.wml.R; +import org.docx4j.wml.RPr; +import org.docx4j.wml.Tbl; +import org.docx4j.wml.Tc; +import org.docx4j.wml.Text; +import org.docx4j.wml.Tr; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import java.io.File; +import java.nio.file.Files; +import java.util.List; + +class Docx4jExample { + + void createDocumentPackage(String outputPath, String imagePath) throws Exception { + WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage(); + MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart(); + mainDocumentPart.addStyledParagraphOfText("Title", "Hello World!"); + mainDocumentPart.addParagraphOfText("Welcome To Baeldung!"); + + ObjectFactory factory = Context.getWmlObjectFactory(); + P p = factory.createP(); + R r = factory.createR(); + Text t = factory.createText(); + t.setValue("Welcome To Baeldung"); + r.getContent().add(t); + p.getContent().add(r); + RPr rpr = factory.createRPr(); + BooleanDefaultTrue b = new BooleanDefaultTrue(); + rpr.setB(b); + rpr.setI(b); + rpr.setCaps(b); + Color red = factory.createColor(); + red.setVal("green"); + rpr.setColor(red); + r.setRPr(rpr); + mainDocumentPart.getContent().add(p); + + File image = new File(imagePath); + byte[] fileContent = Files.readAllBytes(image.toPath()); + BinaryPartAbstractImage imagePart = BinaryPartAbstractImage + .createImagePart(wordPackage, fileContent); + Inline inline = imagePart.createImageInline( + "Baeldung Image", "Alt Text", 1, 2, false); + P Imageparagraph = addImageToParagraph(inline); + mainDocumentPart.getContent().add(Imageparagraph); + + int writableWidthTwips = wordPackage.getDocumentModel() + .getSections().get(0).getPageDimensions() + .getWritableWidthTwips(); + int columnNumber = 3; + Tbl tbl = TblFactory.createTable(3, 3, writableWidthTwips / columnNumber); + List rows = tbl.getContent(); + for (Object row : rows) { + Tr tr = (Tr) row; + List cells = tr.getContent(); + for (Object cell : cells) { + Tc td = (Tc) cell; + td.getContent().add(p); + } + } + + mainDocumentPart.getContent().add(tbl); + File exportFile = new File(outputPath); + wordPackage.save(exportFile); + } + + boolean isTextExist(String testText) throws Docx4JException, JAXBException { + File doc = new File("helloWorld.docx"); + WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(doc); + MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart(); + String textNodesXPath = "//w:t"; + List paragraphs = mainDocumentPart.getJAXBNodesViaXPath(textNodesXPath, true); + for (Object obj : paragraphs) { + Text text = (Text) ((JAXBElement) obj).getValue(); + String textValue = text.getValue(); + if (textValue != null && textValue.contains(testText)) { + return true; + } + } + return false; + } + + private static P addImageToParagraph(Inline inline) { + ObjectFactory factory = new ObjectFactory(); + P p = factory.createP(); + R r = factory.createR(); + p.getContent().add(r); + Drawing drawing = factory.createDrawing(); + r.getContent().add(drawing); + drawing.getAnchorOrInline().add(inline); + return p; + } +} diff --git a/libraries/src/main/java/com/baeldung/fj/FunctionalJavaIOMain.java b/libraries/src/main/java/com/baeldung/fj/FunctionalJavaIOMain.java new file mode 100644 index 0000000000..ebf0fa4d2d --- /dev/null +++ b/libraries/src/main/java/com/baeldung/fj/FunctionalJavaIOMain.java @@ -0,0 +1,47 @@ +package com.baeldung.fj; + +import fj.F; +import fj.F1Functions; +import fj.Unit; +import fj.data.IO; +import fj.data.IOFunctions; + +public class FunctionalJavaIOMain { + + public static IO printLetters(final String s) { + return () -> { + for (int i = 0; i < s.length(); i++) { + System.out.println(s.charAt(i)); + } + return Unit.unit(); + }; + } + + public static void main(String[] args) { + + F> printLetters = i -> printLetters(i); + + IO lowerCase = IOFunctions + .stdoutPrintln("What's your first Name ?"); + + IO input = IOFunctions.stdoutPrint("First Name: "); + + IO userInput = IOFunctions.append(lowerCase, input); + + IO readInput = IOFunctions.stdinReadLine(); + + F toUpperCase = i -> i.toUpperCase(); + + F> transformInput = F1Functions + ., String> o(printLetters).f(toUpperCase); + + IO readAndPrintResult = IOFunctions.bind(readInput, + transformInput); + + IO program = IOFunctions.bind(userInput, + nothing -> readAndPrintResult); + + IOFunctions.toSafe(program).run(); + + } +} diff --git a/libraries/src/main/java/com/baeldung/fj/FunctionalJavaMain.java b/libraries/src/main/java/com/baeldung/fj/FunctionalJavaMain.java new file mode 100644 index 0000000000..e4d731454d --- /dev/null +++ b/libraries/src/main/java/com/baeldung/fj/FunctionalJavaMain.java @@ -0,0 +1,48 @@ +package com.baeldung.fj; + +import fj.F; +import fj.Show; +import fj.data.Array; +import fj.data.List; +import fj.data.Option; +import fj.function.Characters; +import fj.function.Integers; + +public class FunctionalJavaMain { + + public static final F isEven = i -> i % 2 == 0; + + public static void main(String[] args) { + + List fList = List.list(3, 4, 5, 6); + List evenList = fList.map(isEven); + Show.listShow(Show.booleanShow).println(evenList); + + fList = fList.map(i -> i + 1); + Show.listShow(Show.intShow).println(fList); + + Array a = Array.array(17, 44, 67, 2, 22, 80, 1, 27); + Array b = a.filter(Integers.even); + Show.arrayShow(Show.intShow).println(b); + + Array array = Array.array("Welcome", "To", "baeldung"); + Boolean isExist = array.exists(s -> List.fromString(s).forall(Characters.isLowerCase)); + System.out.println(isExist); + + Array intArray = Array.array(17, 44, 67, 2, 22, 80, 1, 27); + int sum = intArray.foldLeft(Integers.add, 0); + System.out.println(sum); + + Option n1 = Option.some(1); + Option n2 = Option.some(2); + + F> f1 = i -> i % 2 == 0 ? Option.some(i + 100) : Option.none(); + + Option result1 = n1.bind(f1); + Option result2 = n2.bind(f1); + + Show.optionShow(Show.intShow).println(result1); + Show.optionShow(Show.intShow).println(result2); + } + +} diff --git a/libraries/src/main/java/com/baeldung/googlehttpclientguide/GitHubExample.java b/libraries/src/main/java/com/baeldung/googlehttpclientguide/GitHubExample.java new file mode 100644 index 0000000000..0618a7294d --- /dev/null +++ b/libraries/src/main/java/com/baeldung/googlehttpclientguide/GitHubExample.java @@ -0,0 +1,65 @@ +package com.baeldung.googlehttpclientguide; + +import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler; +import com.google.api.client.http.HttpRequest; +import com.google.api.client.http.HttpRequestFactory; +import com.google.api.client.http.HttpResponse; +import com.google.api.client.http.HttpResponseException; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.http.apache.ApacheHttpTransport; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.JsonFactory; +import com.google.api.client.json.JsonObjectParser; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.client.util.ExponentialBackOff; +import com.google.gson.reflect.TypeToken; +import java.lang.reflect.Type; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +public class GitHubExample { + static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); + //static final HttpTransport HTTP_TRANSPORT = new ApacheHttpTransport(); + static final JsonFactory JSON_FACTORY = new JacksonFactory(); + //static final JsonFactory JSON_FACTORY = new GsonFactory(); + + private static void run() throws Exception { + HttpRequestFactory requestFactory + = HTTP_TRANSPORT.createRequestFactory( + (HttpRequest request) -> { + request.setParser(new JsonObjectParser(JSON_FACTORY)); + }); + GitHubUrl url = new GitHubUrl("https://api.github.com/users"); + url.per_page = 10; + url.page = 1; + HttpRequest request = requestFactory.buildGetRequest(url); + ExponentialBackOff backoff = new ExponentialBackOff.Builder() + .setInitialIntervalMillis(500) + .setMaxElapsedTimeMillis(900000) + .setMaxIntervalMillis(6000) + .setMultiplier(1.5) + .setRandomizationFactor(0.5) + .build(); + request.setUnsuccessfulResponseHandler(new HttpBackOffUnsuccessfulResponseHandler(backoff)); + Type type = new TypeToken>() {}.getType(); + List users = (List)request.execute().parseAs(type); + System.out.println(users); + url.appendRawPath("/eugenp"); + request = requestFactory.buildGetRequest(url); + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future responseFuture = request.executeAsync(executor); + User eugen = responseFuture.get().parseAs(User.class); + System.out.println(eugen); + executor.shutdown(); + } + + public static void main(String[] args) { + try { + run(); + } catch (Exception e) { + System.err.println(e.getMessage()); + } + } +} diff --git a/libraries/src/main/java/com/baeldung/googlehttpclientguide/GitHubUrl.java b/libraries/src/main/java/com/baeldung/googlehttpclientguide/GitHubUrl.java new file mode 100644 index 0000000000..c44de1e145 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/googlehttpclientguide/GitHubUrl.java @@ -0,0 +1,18 @@ +package com.baeldung.googlehttpclientguide; + +import com.google.api.client.http.GenericUrl; +import com.google.api.client.util.Key; + +public class GitHubUrl extends GenericUrl{ + + public GitHubUrl(String encodedUrl) { + super(encodedUrl); + } + + @Key + public int per_page; + + @Key + public int page; + +} diff --git a/libraries/src/main/java/com/baeldung/googlehttpclientguide/User.java b/libraries/src/main/java/com/baeldung/googlehttpclientguide/User.java new file mode 100644 index 0000000000..bf4ee96b25 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/googlehttpclientguide/User.java @@ -0,0 +1,77 @@ +package com.baeldung.googlehttpclientguide; + +import com.google.api.client.json.GenericJson; +import com.google.api.client.util.Key; + +public class User extends GenericJson { + @Key + private String login; + @Key + private long id; + @Key + private String url; + @Key + private String company; + @Key + private String blog; + @Key + private String email; + + @Key("subscriptions_url") + private String subscriptionsUrl; + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + + public String getBlog() { + return blog; + } + + public void setBlog(String blog) { + this.blog = blog; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public String toString() { + return "User{" + "login=" + login + ", id=" + id + ", url=" + url + ", company=" + company + ", blog=" + blog + ", email=" + email + '}'; + } + + +} diff --git a/libraries/src/main/java/com/baeldung/googlehttpclientguide/logging.properties b/libraries/src/main/java/com/baeldung/googlehttpclientguide/logging.properties new file mode 100644 index 0000000000..02489378df --- /dev/null +++ b/libraries/src/main/java/com/baeldung/googlehttpclientguide/logging.properties @@ -0,0 +1,10 @@ +# Properties file which configures the operation of the JDK logging facility. +# The system will look for this config file to be specified as a system property: +# -Djava.util.logging.config.file=${project_loc:dailymotion-simple-cmdline-sample}/logging.properties + +# Set up the console handler (uncomment "level" to show more fine-grained messages) +handlers = java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level = ALL + +# Set up logging of HTTP requests and responses (uncomment "level" to show) +com.google.api.client.http.level = ALL diff --git a/libraries/src/main/java/com/baeldung/jcache/SimpleCacheEntryListener.java b/libraries/src/main/java/com/baeldung/jcache/SimpleCacheEntryListener.java new file mode 100644 index 0000000000..b58182eab0 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jcache/SimpleCacheEntryListener.java @@ -0,0 +1,34 @@ +package com.baeldung.jcache; + +import java.io.Serializable; + +import javax.cache.event.CacheEntryCreatedListener; +import javax.cache.event.CacheEntryEvent; +import javax.cache.event.CacheEntryListenerException; +import javax.cache.event.CacheEntryUpdatedListener; + +public class SimpleCacheEntryListener implements CacheEntryCreatedListener, CacheEntryUpdatedListener, Serializable { + + /** + * + */ + private static final long serialVersionUID = -712657810462878763L; + private boolean updated; + private boolean created; + + public boolean getUpdated() { + return this.updated; + } + + public boolean getCreated() { + return this.created; + } + + public void onUpdated(Iterable> events) throws CacheEntryListenerException { + this.updated = true; + } + + public void onCreated(Iterable> events) throws CacheEntryListenerException { + this.created = true; + } +} \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/jcache/SimpleCacheLoader.java b/libraries/src/main/java/com/baeldung/jcache/SimpleCacheLoader.java new file mode 100644 index 0000000000..77ab8fb645 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jcache/SimpleCacheLoader.java @@ -0,0 +1,24 @@ +package com.baeldung.jcache; + +import java.util.HashMap; +import java.util.Map; + +import javax.cache.integration.CacheLoader; +import javax.cache.integration.CacheLoaderException; + +public class SimpleCacheLoader implements CacheLoader { + + @Override + public String load(Integer key) throws CacheLoaderException { + return "fromCache" + key; + } + + @Override + public Map loadAll(Iterable keys) throws CacheLoaderException { + Map data = new HashMap<>(); + for (int key : keys) { + data.put(key, load(key)); + } + return data; + } +} diff --git a/libraries/src/main/java/com/baeldung/jcache/SimpleEntryProcessor.java b/libraries/src/main/java/com/baeldung/jcache/SimpleEntryProcessor.java new file mode 100644 index 0000000000..bb585807fb --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jcache/SimpleEntryProcessor.java @@ -0,0 +1,25 @@ +package com.baeldung.jcache; + +import java.io.Serializable; + +import javax.cache.processor.EntryProcessor; +import javax.cache.processor.EntryProcessorException; +import javax.cache.processor.MutableEntry; + +public class SimpleEntryProcessor implements EntryProcessor, Serializable { + + /** + * + */ + private static final long serialVersionUID = -5616476363722945132L; + + public String process(MutableEntry entry, Object... args) throws EntryProcessorException { + + if (entry.exists()) { + String current = entry.getValue(); + entry.setValue(current + " - modified"); + return current; + } + return null; + } +} diff --git a/libraries/src/main/java/com/baeldung/jdeffered/FilterDemo.java b/libraries/src/main/java/com/baeldung/jdeffered/FilterDemo.java index fc33824b6f..ec2c52d3b5 100644 --- a/libraries/src/main/java/com/baeldung/jdeffered/FilterDemo.java +++ b/libraries/src/main/java/com/baeldung/jdeffered/FilterDemo.java @@ -4,25 +4,21 @@ import org.jdeferred.Deferred; import org.jdeferred.Promise; import org.jdeferred.impl.DeferredObject; -public class FilterDemo { +class FilterDemo { - static String modifiedMsg; + private static String modifiedMsg; - public static String filter(String msg) { + static String filter(String msg) { - Deferred d = new DeferredObject(); + Deferred d = new DeferredObject<>(); Promise p = d.promise(); Promise filtered = p.then((result) -> { modifiedMsg = "Hello " + result; }); - filtered.done((result) -> { - System.out.println("filtering done"); - }); + filtered.done(r -> System.out.println("filtering done")); d.resolve(msg); return modifiedMsg; - } - } diff --git a/libraries/src/main/java/com/baeldung/jdeffered/PipeDemo.java b/libraries/src/main/java/com/baeldung/jdeffered/PipeDemo.java index f3c72f1847..95250cff76 100644 --- a/libraries/src/main/java/com/baeldung/jdeffered/PipeDemo.java +++ b/libraries/src/main/java/com/baeldung/jdeffered/PipeDemo.java @@ -5,35 +5,31 @@ import org.jdeferred.DonePipe; import org.jdeferred.Promise; import org.jdeferred.impl.DeferredObject; -public class PipeDemo { +class PipeDemo { - public static enum Result { + public enum Result { SUCCESS, FAILURE }; - static Result status; + private static Result status; - public static Result validate(int num) { - Deferred d = new DeferredObject(); + static Result validate(int num) { + Deferred d = new DeferredObject<>(); Promise p = d.promise(); - p.then(new DonePipe() { - public Deferred pipeDone(Integer result) { - if (result < 90) { - return new DeferredObject().resolve(result); - } else { - return new DeferredObject().reject(new Exception("Unacceptable value")); - } + p.then((DonePipe) result -> { + if (result < 90) { + return new DeferredObject() + .resolve(result); + } else { + return new DeferredObject() + .reject(new Exception("Unacceptable value")); } - }).done((result) -> { - status = Result.SUCCESS; - }).fail((result) -> { - status = Result.FAILURE; - }); + }).done(r -> status = Result.SUCCESS) + .fail(r -> status = Result.FAILURE); d.resolve(num); return status; } - } diff --git a/libraries/src/main/java/com/baeldung/jdeffered/PromiseDemo.java b/libraries/src/main/java/com/baeldung/jdeffered/PromiseDemo.java index 7e38afc3ac..2a9f83dc35 100644 --- a/libraries/src/main/java/com/baeldung/jdeffered/PromiseDemo.java +++ b/libraries/src/main/java/com/baeldung/jdeffered/PromiseDemo.java @@ -4,22 +4,17 @@ import org.jdeferred.Deferred; import org.jdeferred.Promise; import org.jdeferred.impl.DeferredObject; -public class PromiseDemo { +class PromiseDemo { - public static void startJob(String jobName) { + static void startJob(String jobName) { - Deferred deferred = new DeferredObject(); + Deferred deferred = new DeferredObject<>(); Promise promise = deferred.promise(); - promise.done((result) -> { - System.out.println("Job done"); - }).fail((rejection) -> { - System.out.println("Job fail"); - }).progress((progress) -> { - System.out.println("Job is in progress"); - }).always((state, result, rejection) -> { - System.out.println("Job execution started"); - }); + promise.done(result -> System.out.println("Job done")) + .fail(rejection -> System.out.println("Job fail")) + .progress(progress -> System.out.println("Job is in progress")) + .always((state, result, rejection) -> System.out.println("Job execution started")); deferred.resolve(jobName); // deferred.notify(""); diff --git a/libraries/src/main/java/com/baeldung/jdeffered/ThreadSafeDemo.java b/libraries/src/main/java/com/baeldung/jdeffered/ThreadSafeDemo.java index ae9be964d3..22fd51ed92 100644 --- a/libraries/src/main/java/com/baeldung/jdeffered/ThreadSafeDemo.java +++ b/libraries/src/main/java/com/baeldung/jdeffered/ThreadSafeDemo.java @@ -10,13 +10,11 @@ public class ThreadSafeDemo { public static void task() { DeferredManager dm = new DefaultDeferredManager(); - Deferred deferred = new DeferredObject(); + Deferred deferred = new DeferredObject<>(); Promise p1 = deferred.promise(); - Promise p = dm.when(p1).done((result) -> { - System.out.println("done"); - }).fail((result) -> { - System.out.println("fail"); - }); + Promise p = dm.when(p1) + .done(r -> System.out.println("done")) + .fail(r -> System.out.println("fail")); synchronized (p) { while (p.isPending()) { diff --git a/libraries/src/main/java/com/baeldung/jdeffered/manager/DeferredManagerDemo.java b/libraries/src/main/java/com/baeldung/jdeffered/manager/DeferredManagerDemo.java index 65a720cc3f..d37a62e309 100644 --- a/libraries/src/main/java/com/baeldung/jdeffered/manager/DeferredManagerDemo.java +++ b/libraries/src/main/java/com/baeldung/jdeffered/manager/DeferredManagerDemo.java @@ -6,10 +6,10 @@ import org.jdeferred.Promise; import org.jdeferred.impl.DefaultDeferredManager; import org.jdeferred.impl.DeferredObject; -public class DeferredManagerDemo { +class DeferredManagerDemo { public static void initiate() { - Deferred deferred = new DeferredObject(); + Deferred deferred = new DeferredObject<>(); DeferredManager dm = new DefaultDeferredManager(); Promise p1 = deferred.promise(), p2 = deferred.promise(), p3 = deferred.promise(); dm.when(p1, p2, p3).done((result) -> { @@ -19,5 +19,4 @@ public class DeferredManagerDemo { }); deferred.resolve("Hello Baeldung"); } - } diff --git a/libraries/src/main/java/com/baeldung/jdeffered/manager/DeferredManagerWithExecutorDemo.java b/libraries/src/main/java/com/baeldung/jdeffered/manager/DeferredManagerWithExecutorDemo.java index e4669aab06..2abe9bc10f 100644 --- a/libraries/src/main/java/com/baeldung/jdeffered/manager/DeferredManagerWithExecutorDemo.java +++ b/libraries/src/main/java/com/baeldung/jdeffered/manager/DeferredManagerWithExecutorDemo.java @@ -9,19 +9,16 @@ import org.jdeferred.Promise; import org.jdeferred.impl.DefaultDeferredManager; import org.jdeferred.impl.DeferredObject; -public class DeferredManagerWithExecutorDemo { +class DeferredManagerWithExecutorDemo { public static void initiate() { ExecutorService executor = Executors.newFixedThreadPool(10); - Deferred deferred = new DeferredObject(); + Deferred deferred = new DeferredObject<>(); DeferredManager dm = new DefaultDeferredManager(executor); Promise p1 = deferred.promise(), p2 = deferred.promise(), p3 = deferred.promise(); - dm.when(p1, p2, p3).done((result) -> { - System.out.println("done"); - }).fail((result) -> { - System.out.println("fail"); - }); + dm.when(p1, p2, p3) + .done(r -> System.out.println("done")) + .fail(r -> System.out.println("fail")); deferred.resolve("done"); } - } diff --git a/libraries/src/main/java/com/baeldung/jdeffered/manager/SimpleDeferredManagerDemo.java b/libraries/src/main/java/com/baeldung/jdeffered/manager/SimpleDeferredManagerDemo.java index fc58aa40a2..dc2e82495f 100644 --- a/libraries/src/main/java/com/baeldung/jdeffered/manager/SimpleDeferredManagerDemo.java +++ b/libraries/src/main/java/com/baeldung/jdeffered/manager/SimpleDeferredManagerDemo.java @@ -3,17 +3,12 @@ package com.baeldung.jdeffered.manager; import org.jdeferred.DeferredManager; import org.jdeferred.impl.DefaultDeferredManager; -public class SimpleDeferredManagerDemo { +class SimpleDeferredManagerDemo { public static void initiate() { DeferredManager dm = new DefaultDeferredManager(); - dm.when(() -> { - return 1; - }).done((result) -> { - System.out.println("done"); - }).fail((e) -> { - e.printStackTrace(); - }); + dm.when(() -> 1) + .done(r -> System.out.println("done")) + .fail(Throwable::printStackTrace); } - } diff --git a/libraries/src/main/java/com/baeldung/jdo/query/MyApp.java b/libraries/src/main/java/com/baeldung/jdo/query/MyApp.java new file mode 100644 index 0000000000..384dde48d1 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jdo/query/MyApp.java @@ -0,0 +1,104 @@ +package com.baeldung.jdo.query; + +import java.util.List; + +import javax.jdo.JDOQLTypedQuery; +import javax.jdo.PersistenceManager; +import javax.jdo.PersistenceManagerFactory; +import javax.jdo.Query; + +import org.datanucleus.api.jdo.JDOPersistenceManagerFactory; +import org.datanucleus.metadata.PersistenceUnitMetaData; + +public class MyApp { + + private static PersistenceManagerFactory pmf; + private static PersistenceManager pm; + + public static void main(String[] args) { + + defineDynamicPersistentUnit(); + createTestData(); + queryUsingJDOQL(); + queryUsingTypedJDOQL(); + queryUsingSQL(); + queryUsingJPQL(); + + } + + public static void createTestData(){ + ProductItem item1 = new ProductItem("supportedItem", "price less than 10", "SoldOut",5); + ProductItem item2 = new ProductItem("pro2", "price less than 10","InStock", 8); + ProductItem item3 = new ProductItem("pro3", "price more than 10","SoldOut", 15); + + if( pm != null ){ + pm.makePersistent(item1); + pm.makePersistent(item2); + pm.makePersistent(item3); + } + } + + public static void defineDynamicPersistentUnit(){ + + PersistenceUnitMetaData pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); + pumd.addProperty("javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost:3306/jdo_db"); + pumd.addProperty("javax.jdo.option.ConnectionUserName", "root"); + pumd.addProperty("javax.jdo.option.ConnectionPassword", "admin"); + pumd.addProperty("javax.jdo.option.ConnectionDriverName", "com.mysql.jdbc.Driver"); + pumd.addProperty("datanucleus.schema.autoCreateAll", "true"); + + pmf = new JDOPersistenceManagerFactory(pumd, null); + pm = pmf.getPersistenceManager(); + } + + public static void queryUsingJDOQL(){ + + Query query = pm.newQuery("SELECT FROM com.baeldung.jdo.query.ProductItem " + + "WHERE price < threshold PARAMETERS double threshold"); + List explicitParamResults = (List)query.execute(10); + + query = pm.newQuery("SELECT FROM " + + "com.baeldung.jdo.query.ProductItem WHERE price < :threshold"); + query.setParameters("double threshold"); + List explicitParamResults2 = (List)query.execute(10); + + query = pm.newQuery("SELECT FROM " + + "com.baeldung.jdo.query.ProductItem WHERE price < :threshold"); + List implicitParamResults = (List)query.execute(10); + + } + + public static void queryUsingTypedJDOQL(){ + + JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(ProductItem.class); + QProductItem cand = QProductItem.candidate(); + tq=tq.filter(cand.price.lt(10).and(cand.name.startsWith("pro"))); + List results = tq.executeList(); + + } + + public static void queryUsingSQL(){ + + Query query = pm.newQuery("javax.jdo.query.SQL","select * from " + + "product_item where price < ? and status = ?"); + query.setClass(ProductItem.class); + query.setParameters(10,"InStock"); + List results = query.executeList(); + + } + + public static void queryUsingJPQL(){ + Query query = pm.newQuery("JPQL","select i from " + + "com.baeldung.jdo.query.ProductItem i where i.price < 10" + + " and i.status = 'InStock'"); + List results = (List) query.execute(); + + } + + public static void namedQuery(){ + Query query = pm.newNamedQuery( + ProductItem.class, "PriceBelow10"); + List results = query.executeList(); + + } +} diff --git a/libraries/src/main/java/com/baeldung/jdo/query/ProductItem.java b/libraries/src/main/java/com/baeldung/jdo/query/ProductItem.java new file mode 100644 index 0000000000..52221a7d97 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jdo/query/ProductItem.java @@ -0,0 +1,68 @@ +package com.baeldung.jdo.query; + +import javax.jdo.annotations.IdGeneratorStrategy; +import javax.jdo.annotations.PersistenceAware; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.Persistent; +import javax.jdo.annotations.PrimaryKey; + +@PersistenceCapable(table = "product_item") +public class ProductItem { + + @PrimaryKey + @Persistent(valueStrategy=IdGeneratorStrategy.INCREMENT) + int id; + String name; + String description; + String status; + double price; + + public ProductItem(){ + + } + + public ProductItem(String name,String description,String status,double price){ + this.name=name; + this.description = description; + this.status = status; + this.price = price; + } + + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public double getPrice() { + return price; + } + public void setPrice(double price) { + this.price = price; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + +} diff --git a/libraries/src/main/java/com/baeldung/jdo/xml/AnnotadedPerson.java b/libraries/src/main/java/com/baeldung/jdo/xml/AnnotadedPerson.java new file mode 100644 index 0000000000..53e86524a5 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jdo/xml/AnnotadedPerson.java @@ -0,0 +1,72 @@ +package com.baeldung.jdo.xml; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.jdo.annotations.Element; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.PrimaryKey; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; + +@PersistenceCapable( + schema="/myproduct/people", + table="person" + ) +public class AnnotadedPerson { + @XmlAttribute + private long personNum; + + @PrimaryKey + private String firstName; + private String lastName; + + @XmlElementWrapper(name="phone-numbers") + @XmlElement(name="phone-number") + @Element(types=String.class) + private List phoneNumbers = new ArrayList(); + + + public AnnotadedPerson(long personNum, String firstName, String lastName) { + super(); + this.personNum = personNum; + this.firstName = firstName; + this.lastName = lastName; + } + + public long getPersonNum() { + return personNum; + } + + public void setPersonNum(long personNum) { + this.personNum = personNum; + } + + 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 List getPhoneNumbers() { + return phoneNumbers; + } + + public void setPhoneNumbers(List phoneNumbers) { + this.phoneNumbers = phoneNumbers; + } + +} diff --git a/libraries/src/main/java/com/baeldung/jdo/xml/MyApp.java b/libraries/src/main/java/com/baeldung/jdo/xml/MyApp.java new file mode 100644 index 0000000000..97ec49eec1 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jdo/xml/MyApp.java @@ -0,0 +1,105 @@ +package com.baeldung.jdo.xml; + +import java.util.List; + +import javax.jdo.JDOHelper; +import javax.jdo.PersistenceManager; +import javax.jdo.PersistenceManagerFactory; +import javax.jdo.Query; +import javax.jdo.Transaction; + +import org.datanucleus.api.jdo.JDOPersistenceManagerFactory; +import org.datanucleus.metadata.PersistenceUnitMetaData; + +public class MyApp { + + private static PersistenceUnitMetaData pumd; + private static PersistenceManagerFactory pmf; + private static PersistenceManager pm; + + public static void main( String[] args ) { + + //persist product object using dynamic persistence unit + defineDynamicPersistentUnit(); + Product product = new Product("id1","Sony Discman", "A standard discman from Sony", 49.99); + persistObject(product); + closePersistenceManager(); + + //persist AnnotatedPerson object using named pmf + defineNamedPersistenceManagerFactory("XmlDatastore"); + AnnotadedPerson annotatedPerson = new AnnotadedPerson(654320,"annotated","person"); + annotatedPerson.getPhoneNumbers().add("999999999"); + annotatedPerson.getPhoneNumbers().add("000000000"); + persistObject(annotatedPerson); + queryAnnotatedPersonsInXML(); + closePersistenceManager(); + + //persist Person object using PMF created by properties file + definePersistenceManagerFactoryUsingPropertiesFile("META-INF\\datanucleus.properties"); + Person person = new Person(654321,"bealdung","author"); + person.getPhoneNumbers().add("123456789"); + person.getPhoneNumbers().add("987654321"); + persistObject(person); + queryPersonsInXML(); + closePersistenceManager(); + } + + public static void defineDynamicPersistentUnit(){ + + PersistenceUnitMetaData pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); + pumd.addProperty("javax.jdo.option.ConnectionURL", "xml:file:myfile_dynamicPMF.xml"); + pumd.addProperty("datanucleus.schema.autoCreateAll", "true"); + pumd.addProperty("datanucleus.xml.indentSize", "4"); + + pmf = new JDOPersistenceManagerFactory(pumd, null); + pm = pmf.getPersistenceManager(); + } + + public static void defineNamedPersistenceManagerFactory(String pmfName){ + + pmf = JDOHelper.getPersistenceManagerFactory("XmlDatastore"); + pm = pmf.getPersistenceManager(); + } + + public static void definePersistenceManagerFactoryUsingPropertiesFile(String filePath){ + + pmf = JDOHelper.getPersistenceManagerFactory(filePath); + pm = pmf.getPersistenceManager(); + } + + public static void closePersistenceManager(){ + + if(pm!=null && !pm.isClosed()){ + pm.close(); + } + } + + public static void persistObject(Object obj){ + + Transaction tx = pm.currentTransaction(); + + try { + tx.begin(); + pm.makePersistent(obj); + tx.commit(); + } finally { + if (tx.isActive()) { + tx.rollback(); + } + } + } + + public static void queryPersonsInXML(){ + + Query query = pm.newQuery(Person.class); + List result = query.executeList(); + System.out.println("name: "+result.get(0).getFirstName()); + } + + public static void queryAnnotatedPersonsInXML(){ + + Query query = pm.newQuery(AnnotadedPerson.class); + List result = query.executeList(); + System.out.println("name: "+result.get(0).getFirstName()); + } +} diff --git a/libraries/src/main/java/com/baeldung/jdo/xml/Person.java b/libraries/src/main/java/com/baeldung/jdo/xml/Person.java new file mode 100644 index 0000000000..e3ec5c6bab --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jdo/xml/Person.java @@ -0,0 +1,65 @@ +package com.baeldung.jdo.xml; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.jdo.annotations.Element; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.PrimaryKey; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; + + +@PersistenceCapable +public class Person { + private long personNum; + + @PrimaryKey + private String firstName; + private String lastName; + + private List phoneNumbers = new ArrayList(); + + public Person(long personNum, String firstName, String lastName) { + super(); + this.personNum = personNum; + this.firstName = firstName; + this.lastName = lastName; + } + + public long getPersonNum() { + return personNum; + } + + public void setPersonNum(long personNum) { + this.personNum = personNum; + } + + 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 List getPhoneNumbers() { + return phoneNumbers; + } + + public void setPhoneNumbers(List phoneNumbers) { + this.phoneNumbers = phoneNumbers; + } + +} diff --git a/libraries/src/main/java/com/baeldung/jdo/xml/Product.java b/libraries/src/main/java/com/baeldung/jdo/xml/Product.java new file mode 100644 index 0000000000..d8d3bb17b2 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jdo/xml/Product.java @@ -0,0 +1,58 @@ +package com.baeldung.jdo.xml; + +import javax.jdo.annotations.IdGeneratorStrategy; +import javax.jdo.annotations.PersistenceAware; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.Persistent; +import javax.jdo.annotations.PrimaryKey; + +@PersistenceCapable +public class Product { + + @PrimaryKey + String id; + String name; + String description; + double price; + + public Product(){ + + } + + public Product(String id,String name,String description,double price){ + this.id = id; + this.name=name; + this.description = description; + this.price = price; + } + + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public double getPrice() { + return price; + } + public void setPrice(double price) { + this.price = price; + } + + +} diff --git a/libraries/src/main/java/com/baeldung/javax/measure/WaterTank.java b/libraries/src/main/java/com/baeldung/measurement/WaterTank.java similarity index 62% rename from libraries/src/main/java/com/baeldung/javax/measure/WaterTank.java rename to libraries/src/main/java/com/baeldung/measurement/WaterTank.java index 1ab9eee53f..f3675ae689 100644 --- a/libraries/src/main/java/com/baeldung/javax/measure/WaterTank.java +++ b/libraries/src/main/java/com/baeldung/measurement/WaterTank.java @@ -1,14 +1,14 @@ -package com.baeldung.javax.measure; +package com.baeldung.measurement; -import javax.measure.Measure; +import javax.measure.Quantity; import javax.measure.quantity.Volume; public class WaterTank { - private Measure capacityMeasure; + private Quantity capacityMeasure; private double capacityDouble; - public void setCapacityMeasure(Measure capacityMeasure) { + public void setCapacityMeasure(Quantity capacityMeasure) { this.capacityMeasure = capacityMeasure; } @@ -16,7 +16,7 @@ public class WaterTank { this.capacityDouble = capacityDouble; } - public Measure getCapacityMeasure() { + public Quantity getCapacityMeasure() { return capacityMeasure; } diff --git a/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApp.java b/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApp.java index 54a130a67e..6b2cd14252 100644 --- a/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApp.java +++ b/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicApp.java @@ -4,11 +4,11 @@ import java.io.IOException; import java.util.List; public class GitHubBasicApp { - + public static void main(String[] args) throws IOException { String userName = "eugenp"; - List topContributors = new GitHubBasicService().getTopContributors(userName); - topContributors.stream().forEach(System.out::println); + List topContributors = new GitHubBasicService() + .getTopContributors(userName); + topContributors.forEach(System.out::println); } - } diff --git a/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicService.java b/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicService.java index fbfdd96567..20256fb540 100644 --- a/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicService.java +++ b/libraries/src/main/java/com/baeldung/retrofit/basic/GitHubBasicService.java @@ -1,54 +1,60 @@ package com.baeldung.retrofit.basic; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - import com.baeldung.retrofit.models.Contributor; import com.baeldung.retrofit.models.Repository; - import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; -public class GitHubBasicService { - +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +class GitHubBasicService { + private GitHubBasicApi gitHubApi; - - public GitHubBasicService() { + + GitHubBasicService() { Retrofit retrofit = new Retrofit.Builder() - .baseUrl("https://api.github.com/") - .addConverterFactory(GsonConverterFactory.create()) - .build(); - - gitHubApi = retrofit.create(GitHubBasicApi.class); + .baseUrl("https://api.github.com/") + .addConverterFactory(GsonConverterFactory.create()) + .build(); + + gitHubApi = retrofit.create(GitHubBasicApi.class); } - - public List getTopContributors(String userName) throws IOException { + + List getTopContributors(String userName) throws IOException { List repos = gitHubApi .listRepos(userName) .execute() .body(); - - List topContributors = new ArrayList<>(); - for(Repository repo : repos) { - List contributers = gitHubApi - .listRepoContributors(userName, repo.getName()) - .execute() - .body(); - - List repoTopContributors = contributers.stream() - .filter(c -> c.getContributions() > 100) - .collect(Collectors.toList()); - topContributors.addAll(repoTopContributors); - } - - Collections.sort(topContributors, (a, b) -> b.getContributions() - a.getContributions()); - return topContributors.stream() - .map(c -> c.getName()) + + repos = repos != null ? repos : Collections.emptyList(); + + return repos.stream() + .flatMap(repo -> getContributors(userName, repo)) + .sorted((a, b) -> b.getContributions() - a.getContributions()) + .map(Contributor::getName) .distinct() + .sorted() .collect(Collectors.toList()); } + private Stream getContributors(String userName, Repository repo) { + List contributors = null; + try { + contributors = gitHubApi + .listRepoContributors(userName, repo.getName()) + .execute() + .body(); + } catch (IOException e) { + e.printStackTrace(); + } + + contributors = contributors != null ? contributors : Collections.emptyList(); + + return contributors.stream() + .filter(c -> c.getContributions() > 100); + } } diff --git a/libraries/src/main/java/com/baeldung/retrofit/models/Contributor.java b/libraries/src/main/java/com/baeldung/retrofit/models/Contributor.java index b7b7869ff6..2f8697f603 100644 --- a/libraries/src/main/java/com/baeldung/retrofit/models/Contributor.java +++ b/libraries/src/main/java/com/baeldung/retrofit/models/Contributor.java @@ -2,11 +2,6 @@ package com.baeldung.retrofit.models; import com.google.gson.annotations.SerializedName; -/** - * GitHub Contributer - * @author hany - * - */ public class Contributor { @SerializedName("login") diff --git a/libraries/src/main/java/com/baeldung/retrofit/models/Repository.java b/libraries/src/main/java/com/baeldung/retrofit/models/Repository.java index 61e4752ce7..f12fcdf8f2 100644 --- a/libraries/src/main/java/com/baeldung/retrofit/models/Repository.java +++ b/libraries/src/main/java/com/baeldung/retrofit/models/Repository.java @@ -1,10 +1,5 @@ package com.baeldung.retrofit.models; -/** - * GitHub Repository - * @author hany - * - */ public class Repository { private String name; diff --git a/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxApp.java b/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxApp.java index 0e0d8b1a77..b136a1e40b 100644 --- a/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxApp.java +++ b/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxApp.java @@ -3,11 +3,10 @@ package com.baeldung.retrofit.rx; import java.io.IOException; public class GitHubRxApp { - + public static void main(String[] args) throws IOException { String userName = "eugenp"; new GitHubRxService().getTopContributors(userName) .subscribe(System.out::println); } - } diff --git a/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxService.java b/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxService.java index 56d149d13e..2ad50a9f39 100644 --- a/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxService.java +++ b/libraries/src/main/java/com/baeldung/retrofit/rx/GitHubRxService.java @@ -1,33 +1,33 @@ package com.baeldung.retrofit.rx; +import com.baeldung.retrofit.models.Contributor; import retrofit2.Retrofit; import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; import rx.Observable; -public class GitHubRxService { - +class GitHubRxService { + private GitHubRxApi gitHubApi; - - public GitHubRxService() { + + GitHubRxService() { Retrofit retrofit = new Retrofit.Builder() - .baseUrl("https://api.github.com/") - .addConverterFactory(GsonConverterFactory.create()) - .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) - .build(); - + .baseUrl("https://api.github.com/") + .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .build(); + gitHubApi = retrofit.create(GitHubRxApi.class); } - - public Observable getTopContributors(String userName) { + + Observable getTopContributors(String userName) { return gitHubApi.listRepos(userName) - .flatMap( repos -> Observable.from(repos)) - .flatMap( repo -> gitHubApi.listRepoContributors(userName, repo.getName()) ) - .flatMap( contributers -> Observable.from(contributers)) - .filter( c -> c.getContributions() > 100) - .sorted( (a, b) -> b.getContributions() - a.getContributions() ) - .map( c -> c.getName()) + .flatMapIterable(x -> x) + .flatMap(repo -> gitHubApi.listRepoContributors(userName, repo.getName())) + .flatMapIterable(x -> x) + .filter(c -> c.getContributions() > 100) + .sorted((a, b) -> b.getContributions() - a.getContributions()) + .map(Contributor::getName) .distinct(); } - } diff --git a/libraries/src/main/java/com/baeldung/retrofitguide/GitHubServiceGenerator.java b/libraries/src/main/java/com/baeldung/retrofitguide/GitHubServiceGenerator.java new file mode 100644 index 0000000000..d32891be9e --- /dev/null +++ b/libraries/src/main/java/com/baeldung/retrofitguide/GitHubServiceGenerator.java @@ -0,0 +1,58 @@ +package com.baeldung.retrofitguide; + +import java.io.IOException; +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class GitHubServiceGenerator { + + private static final String BASE_URL = "https://api.github.com/"; + + private static Retrofit.Builder builder + = new Retrofit.Builder() + .baseUrl(BASE_URL) + .addConverterFactory(GsonConverterFactory.create()); + + private static Retrofit retrofit = builder.build(); + + private static OkHttpClient.Builder httpClient + = new OkHttpClient.Builder(); + + private static HttpLoggingInterceptor logging + = new HttpLoggingInterceptor() + .setLevel(HttpLoggingInterceptor.Level.BASIC); + + public static S createService(Class serviceClass) { + if (!httpClient.interceptors().contains(logging)) { + httpClient.addInterceptor(logging); + builder.client(httpClient.build()); + retrofit = builder.build(); + } + return retrofit.create(serviceClass); + } + + public static S createService(Class serviceClass, final String token) { + if (token != null) { + httpClient.interceptors().clear(); + httpClient.addInterceptor(new Interceptor() { + @Override + public Response intercept(Interceptor.Chain chain) throws IOException { + Request original = chain.request(); + Request.Builder builder = original.newBuilder() + .header("Authorization", token); + Request request = builder.build(); + return chain.proceed(request); + } + }); + builder.client(httpClient.build()); + retrofit = builder.build(); + } + return retrofit.create(serviceClass); + } + +} diff --git a/libraries/src/main/java/com/baeldung/retrofitguide/Main.java b/libraries/src/main/java/com/baeldung/retrofitguide/Main.java new file mode 100644 index 0000000000..8a674f634b --- /dev/null +++ b/libraries/src/main/java/com/baeldung/retrofitguide/Main.java @@ -0,0 +1,49 @@ +package com.baeldung.retrofitguide; + +import java.io.IOException; +import okhttp3.OkHttpClient; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class Main { + + public static void main(String[] args) { + //Manual creation + OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); + Retrofit retrofit = new Retrofit.Builder() + .baseUrl("https://api.github.com/") + .addConverterFactory(GsonConverterFactory.create()) + .client(httpClient.build()) + .build(); + UserService service = retrofit.create(UserService.class); + //Using GitHubServiceGenerator + service = GitHubServiceGenerator.createService(UserService.class); + Call callSync = service.getUser("eugenp"); + Call callAsync = service.getUser("eugenp"); + + try { + Response response = callSync.execute(); + User user = response.body(); + System.out.println(user); + } catch (IOException ex) { + } + + // Execute the call asynchronously. Get a positive or negative callback. + callAsync.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + User user = response.body(); + System.out.println(user); + } + + @Override + public void onFailure(Call call, Throwable throwable) { + System.out.println(throwable); + } + }); + + } +} diff --git a/libraries/src/main/java/com/baeldung/retrofitguide/User.java b/libraries/src/main/java/com/baeldung/retrofitguide/User.java new file mode 100644 index 0000000000..1b097aa4f1 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/retrofitguide/User.java @@ -0,0 +1,65 @@ +package com.baeldung.retrofitguide; + +public class User { + + private String login; + private long id; + private String url; + private String company; + private String blog; + private String email; + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + + public String getBlog() { + return blog; + } + + public void setBlog(String blog) { + this.blog = blog; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public String toString() { + return "User{" + "login=" + login + ", id=" + id + ", url=" + url + ", company=" + company + ", blog=" + blog + ", email=" + email + '}'; + } + +} diff --git a/libraries/src/main/java/com/baeldung/retrofitguide/UserService.java b/libraries/src/main/java/com/baeldung/retrofitguide/UserService.java new file mode 100644 index 0000000000..6e18e685ca --- /dev/null +++ b/libraries/src/main/java/com/baeldung/retrofitguide/UserService.java @@ -0,0 +1,17 @@ +package com.baeldung.retrofitguide; + +import java.util.List; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Path; +import retrofit2.http.Query; + +public interface UserService { + + @GET("/users") + public Call> getUsers(@Query("per_page") int per_page, @Query("page") int page); + + @GET("/users/{username}") + public Call getUser(@Path("username") String username); + +} diff --git a/libraries/src/main/java/com/baeldung/streamex/Role.java b/libraries/src/main/java/com/baeldung/streamex/Role.java new file mode 100644 index 0000000000..5709ca61f8 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/streamex/Role.java @@ -0,0 +1,5 @@ +package com.baeldung.streamex; + +public class Role { + +} diff --git a/libraries/src/main/java/com/baeldung/streamex/StreamEX.java b/libraries/src/main/java/com/baeldung/streamex/StreamEX.java new file mode 100644 index 0000000000..7cbfec4421 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/streamex/StreamEX.java @@ -0,0 +1,84 @@ +package com.baeldung.streamex; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import one.util.streamex.DoubleStreamEx; +import one.util.streamex.EntryStream; +import one.util.streamex.IntStreamEx; +import one.util.streamex.StreamEx; + +public class StreamEX { + + public static void main(String[] args) { + //Collector shortcut methods (toList, toSet, groupingBy, joining, etc.) + List users = Arrays.asList( + new User("name"), new User(), new User()); + users.stream() + .map(User::getName) + .collect(Collectors.toList()); + List userNames = StreamEx.of(users) + .map(User::getName) + .toList(); + Map> role2users = StreamEx.of(users) + .groupingBy(User::getRole); + StreamEx.of(1, 2, 3).joining("; "); // "1; 2; 3" + //Selecting stream elements of specific type + List usersAndRoles = Arrays.asList(new User(), new Role()); + List roles = IntStreamEx.range(usersAndRoles.size()) + .mapToObj(usersAndRoles::get) + .select(Role.class) + .toList(); + System.out.println(roles); + //adding elements to Stream + List appendedUsers = StreamEx.of(users) + .map(User::getName) + .prepend("(none)") + .append("LAST") + .toList(); + System.out.println(appendedUsers); + //Removing unwanted elements and using the stream as Iterable: + for (String line : StreamEx.of(users).map(User::getName) + .nonNull()) { + System.out.println(line); + } + //Selecting map keys by value predicate: + Map nameToRole = new HashMap<>(); + nameToRole.put("first", new Role()); + nameToRole.put("second", null); + Set nonNullRoles = StreamEx. + ofKeys(nameToRole, Objects::nonNull) + .toSet(); + System.out.println(nonNullRoles); + //Operating on key-value pairs: + Map> users2roles = transformMap(role2users); + Map mapToString = EntryStream.of(users2roles) + .mapKeys(String::valueOf) + .mapValues(String::valueOf) + .toMap(); + //Support of byte/char/short/float types: + short[] src = {1, 2, 3}; + char[] output = IntStreamEx.of(src) + .map(x -> x * 5) + .toCharArray(); + } + + public double[] getDiffBetweenPairs(double... numbers) { + return DoubleStreamEx.of(numbers) + .pairMap((a, b) -> b - a).toArray(); + } + + public static Map> transformMap( + Map> role2users) { + Map> users2roles = EntryStream.of(role2users) + .flatMapValues(List::stream) + .invert() + .grouping(); + return users2roles; + } + +} diff --git a/libraries/src/main/java/com/baeldung/streamex/User.java b/libraries/src/main/java/com/baeldung/streamex/User.java new file mode 100644 index 0000000000..e37eb014c5 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/streamex/User.java @@ -0,0 +1,40 @@ +package com.baeldung.streamex; + +public class User { + + int id; + String name; + Role role = new Role(); + + public User() { + } + + public User(String name) { + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + +} diff --git a/libraries/src/main/resources/Baeldung.cer b/libraries/src/main/resources/Baeldung.cer new file mode 100644 index 0000000000..72d0918424 --- /dev/null +++ b/libraries/src/main/resources/Baeldung.cer @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIJAPvd1gx14C3CMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV +BAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNhYmxhbmNhMREw +DwYDVQQDEwhCYWVsZHVuZzAeFw0xNzEwMTIxMDQzMTRaFw0yNzEwMTMxMDQzMTRa +MEcxCzAJBgNVBAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNh +YmxhbmNhMREwDwYDVQQDEwhCYWVsZHVuZzCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMyi5GmOeN4QaH/CP5gSOyHX8znb5TDHWV8wc+ZT7kNU8zt5tGMh +jozK6hax155/6tOsBDR0rSYBhL+Dm/+uCVS7qOlRHhf6cNGtzGF1gnNJB2WjI8oM +AYm24xpLj1WphKUwKrn3nTMPnQup5OoNAMYl99flANrRYVjjxrLQvDZDUio6Iujr +CZ2TtXGM0g/gP++28KT7g1KlUui3xtB0u33wx7UN8Fix3JmjOaPHGwxGpwP3VGSj +fs8cuhqVwRQaZpCOoHU/P8wpXKw80sSdhz+SRueMPtVYqK0CiLL5/O0h0Y3le4IV +whgg3KG1iTGOWn60UMFn1EYmQ18k5Nsma6UCAwEAAaMtMCswCQYDVR0TBAIwADAR +BglghkgBhvhCAQEEBAMCBPAwCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBBQUAA4IB +AQC8DDBmJ3p4xytxBiE0s4p1715WT6Dm/QJHp0XC0hkSoyZKDh+XVmrzm+J3SiW1 +vpswb5hLgPo040YX9jnDmgOD+TpleTuKHxZRYj92UYWmdjkWLVtFMcvOh+gxBiAP +pHIqZsqo8lfcyAuh8Jx834IXbknfCUtERDLG/rU9P/3XJhrM2GC5qPQznrW4EYhU +CGPyIJXmvATMVvXMWCtfogAL+n42vjYXQXZoAWomHhLHoNbSJUErnNdWDOh4WoJt +XJCxA6U5LSBplqb3wB2hUTqw+0admKltvmy+KA1PD7OxoGiY7V544zeGqJam1qxU +ia7y5BL6uOa/4ShSV8pcJDYz +-----END CERTIFICATE----- diff --git a/libraries/src/main/resources/Baeldung.p12 b/libraries/src/main/resources/Baeldung.p12 new file mode 100644 index 0000000000..65ec8bc8fe Binary files /dev/null and b/libraries/src/main/resources/Baeldung.p12 differ diff --git a/libraries/src/main/resources/META-INF/datanucleus.properties b/libraries/src/main/resources/META-INF/datanucleus.properties new file mode 100644 index 0000000000..a3cd4a450a --- /dev/null +++ b/libraries/src/main/resources/META-INF/datanucleus.properties @@ -0,0 +1,4 @@ +javax.jdo.PersistenceManagerFactoryClass=org.datanucleus.api.jdo.JDOPersistenceManagerFactory +javax.jdo.option.ConnectionURL= xml:file:myfile-ds.xml +datanucleus.xml.indentSize=6 +datanucleus.schema.autoCreateAll=true \ No newline at end of file diff --git a/libraries/src/main/resources/META-INF/jdoconfig.xml b/libraries/src/main/resources/META-INF/jdoconfig.xml new file mode 100644 index 0000000000..77da460686 --- /dev/null +++ b/libraries/src/main/resources/META-INF/jdoconfig.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/src/main/resources/META-INF/package.jdo b/libraries/src/main/resources/META-INF/package.jdo new file mode 100644 index 0000000000..d3cf501bb6 --- /dev/null +++ b/libraries/src/main/resources/META-INF/package.jdo @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/src/main/resources/image.jpg b/libraries/src/main/resources/image.jpg new file mode 100644 index 0000000000..e2554a0d9c Binary files /dev/null and b/libraries/src/main/resources/image.jpg differ diff --git a/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceLongRunningUnitTest.java b/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceLongRunningUnitTest.java index d17a7dcf1b..7ca656efbf 100644 --- a/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceLongRunningUnitTest.java +++ b/libraries/src/test/java/com/baeldung/awaitility/AsyncServiceLongRunningUnitTest.java @@ -1,6 +1,5 @@ package com.baeldung.awaitility; -import org.awaitility.Awaitility; import org.awaitility.Duration; import org.junit.Before; import org.junit.Test; diff --git a/libraries/src/test/java/com/baeldung/bouncycastle/BouncyCastleLiveTest.java b/libraries/src/test/java/com/baeldung/bouncycastle/BouncyCastleLiveTest.java new file mode 100644 index 0000000000..3965eeecd4 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/bouncycastle/BouncyCastleLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.bouncycastle; + +import static org.junit.Assert.assertTrue; + +import java.io.FileInputStream; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; +import java.security.Security; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.OperatorCreationException; +import org.junit.Test; + +public class BouncyCastleLiveTest { + + String certificatePath = "src/main/resources/Baeldung.cer"; + String privateKeyPath = "src/main/resources/Baeldung.p12"; + char[] p12Password = "password".toCharArray(); + char[] keyPassword = "password".toCharArray(); + + @Test + public void givenCryptographicResource_whenOperationSuccess_returnTrue() + throws CertificateException, NoSuchProviderException, NoSuchAlgorithmException, IOException, + KeyStoreException, UnrecoverableKeyException, CMSException, OperatorCreationException { + Security.addProvider(new BouncyCastleProvider()); + + CertificateFactory certFactory = CertificateFactory.getInstance("X.509", "BC"); + X509Certificate certificate = (X509Certificate) certFactory + .generateCertificate(new FileInputStream(certificatePath)); + KeyStore keystore = KeyStore.getInstance("PKCS12"); + keystore.load(new FileInputStream(privateKeyPath), p12Password); + PrivateKey privateKey = (PrivateKey) keystore.getKey("baeldung", keyPassword); + String secretMessage = "My password is 123456Seven"; + System.out.println("Original Message : " + secretMessage); + byte[] stringToEncrypt = secretMessage.getBytes(); + byte[] encryptedData = BouncyCastleCrypto.encryptData(stringToEncrypt, certificate); + byte[] rawData = BouncyCastleCrypto.decryptData(encryptedData, privateKey); + String decryptedMessage = new String(rawData); + assertTrue(decryptedMessage.equals(secretMessage)); + byte[] signedData = BouncyCastleCrypto.signData(rawData, certificate, privateKey); + Boolean check = BouncyCastleCrypto.verifSignData(signedData); + assertTrue(check); + } +} diff --git a/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java new file mode 100644 index 0000000000..56dbda5974 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/caffeine/CaffeineUnitTest.java @@ -0,0 +1,174 @@ +package com.baeldung.caffeine; + +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nonnull; + +import org.junit.Test; + +import com.github.benmanes.caffeine.cache.*; + +public class CaffeineUnitTest { + + @Test + public void givenCache_whenPopulate_thenValueStored() { + Cache cache = Caffeine.newBuilder() + .expireAfterWrite(1, TimeUnit.MINUTES) + .maximumSize(100) + .build(); + + String key = "A"; + DataObject dataObject = cache.getIfPresent(key); + + assertNull(dataObject); + + dataObject = cache.get(key, k -> DataObject.get("Data for A")); + + assertNotNull(dataObject); + assertEquals("Data for A", dataObject.getData()); + + cache.put(key, dataObject); + dataObject = cache.getIfPresent(key); + + assertNotNull(dataObject); + + cache.invalidate(key); + dataObject = cache.getIfPresent(key); + + assertNull(dataObject); + } + + @Test + public void givenLoadingCache_whenGet_thenValuePopulated() { + LoadingCache cache = Caffeine.newBuilder() + .maximumSize(100) + .expireAfterWrite(1, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); + String key = "A"; + + DataObject dataObject = cache.get(key); + + assertNotNull(dataObject); + assertEquals("Data for " + key, dataObject.getData()); + + Map dataObjectMap = cache.getAll(Arrays.asList("A", "B", "C")); + + assertEquals(3, dataObjectMap.size()); + } + + @Test + public void givenAsyncLoadingCache_whenGet_thenValuePopulated() { + + AsyncLoadingCache cache = Caffeine.newBuilder() + .maximumSize(100) + .expireAfterWrite(1, TimeUnit.MINUTES) + .buildAsync(k -> DataObject.get("Data for " + k)); + String key = "A"; + + cache.get(key).thenAccept(dataObject -> { + assertNotNull(dataObject); + assertEquals("Data for " + key, dataObject.getData()); + }); + + cache.getAll(Arrays.asList("A", "B", "C")) + .thenAccept(dataObjectMap -> assertEquals(3, dataObjectMap.size())); + } + + @Test + public void givenLoadingCacheWithSmallSize_whenPut_thenSizeIsConstant() { + LoadingCache cache = Caffeine.newBuilder() + .maximumSize(1) + .refreshAfterWrite(10, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); + + assertEquals(0, cache.estimatedSize()); + + cache.get("A"); + + assertEquals(1, cache.estimatedSize()); + + cache.get("B"); + cache.cleanUp(); + + assertEquals(1, cache.estimatedSize()); + } + + @Test + public void givenLoadingCacheWithWeigher_whenPut_thenSizeIsConstant() { + LoadingCache cache = Caffeine.newBuilder() + .maximumWeight(10) + .weigher((k,v) -> 5) + .build(k -> DataObject.get("Data for " + k)); + + assertEquals(0, cache.estimatedSize()); + + cache.get("A"); + + assertEquals(1, cache.estimatedSize()); + + cache.get("B"); + + assertEquals(2, cache.estimatedSize()); + + cache.get("C"); + cache.cleanUp(); + + assertEquals(2, cache.estimatedSize()); + } + + @Test + public void givenTimeEvictionCache_whenTimeLeft_thenValueEvicted() { + LoadingCache cache = Caffeine.newBuilder() + .expireAfterAccess(5, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); + + cache = Caffeine.newBuilder() + .expireAfterWrite(10, TimeUnit.SECONDS) + .weakKeys() + .weakValues() + .build(k -> DataObject.get("Data for " + k)); + + cache = Caffeine.newBuilder() + .expireAfterWrite(10, TimeUnit.SECONDS) + .softValues() + .build(k -> DataObject.get("Data for " + k)); + + cache = Caffeine.newBuilder().expireAfter(new Expiry() { + @Override + public long expireAfterCreate(@Nonnull String key, @Nonnull DataObject value, long currentTime) { + return value.getData().length() * 1000; + } + + @Override + public long expireAfterUpdate(@Nonnull String key, @Nonnull DataObject value, long currentTime, long currentDuration) { + return currentDuration; + } + + @Override + public long expireAfterRead(@Nonnull String key, @Nonnull DataObject value, long currentTime, long currentDuration) { + return currentDuration; + } + }).build(k -> DataObject.get("Data for " + k)); + + cache = Caffeine.newBuilder() + .refreshAfterWrite(1, TimeUnit.MINUTES) + .build(k -> DataObject.get("Data for " + k)); + } + + @Test + public void givenCache_whenStatsEnabled_thenStatsRecorded() { + LoadingCache cache = Caffeine.newBuilder() + .maximumSize(100) + .recordStats() + .build(k -> DataObject.get("Data for " + k)); + cache.get("A"); + cache.get("A"); + + assertEquals(1, cache.stats().hitCount()); + assertEquals(1, cache.stats().missCount()); + } +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/commons/collections4/BagTests.java b/libraries/src/test/java/com/baeldung/commons/collections4/BagTests.java index 4ce250d979..55fadcbf85 100644 --- a/libraries/src/test/java/com/baeldung/commons/collections4/BagTests.java +++ b/libraries/src/test/java/com/baeldung/commons/collections4/BagTests.java @@ -1,85 +1,111 @@ package com.baeldung.commons.collections4; -import java.util.ArrayList; -import java.util.List; - import org.apache.commons.collections4.Bag; -import org.apache.commons.collections4.bag.CollectionBag; -import org.apache.commons.collections4.bag.HashBag; -import org.apache.commons.collections4.bag.TreeBag; -import org.junit.Assert; -import org.junit.Before; +import org.apache.commons.collections4.SortedBag; +import org.apache.commons.collections4.bag.*; import org.junit.Test; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsEqual.equalTo; + public class BagTests { - - Bag baseBag; - TreeBag treeBag; - - @Before - public void before() { - baseBag = new HashBag(); - treeBag = new TreeBag(); - treeBag = new TreeBag(); - } - - @Test - public void whenAdd_thenRemoveFromBaseBag_thenContainsCorrect() { - baseBag.add("apple", 2); - baseBag.add("lemon", 6); - baseBag.add("lime"); - - baseBag.remove("lemon"); - Assert.assertEquals(3, baseBag.size()); - Assert.assertFalse(baseBag.contains("lemon")); - - Assert.assertTrue(baseBag.uniqueSet().contains("apple")); - - List containList = new ArrayList(); - containList.add("apple"); - containList.add("lemon"); - containList.add("lime"); - Assert.assertFalse(baseBag.containsAll(containList)); - } - - @Test - public void whenAdd_thenRemoveFromBaseCollectionBag_thenContainsCorrect() { - baseBag.add("apple", 2); - baseBag.add("lemon", 6); - baseBag.add("lime"); - - CollectionBag baseCollectionBag = new CollectionBag( - baseBag); - - baseCollectionBag.remove("lemon"); - Assert.assertEquals(8, baseCollectionBag.size()); - Assert.assertTrue(baseCollectionBag.contains("lemon")); - - baseCollectionBag.remove("lemon",1); - Assert.assertEquals(7, baseCollectionBag.size()); - - Assert.assertTrue(baseBag.uniqueSet().contains("apple")); - - List containList = new ArrayList(); - containList.add("apple"); - containList.add("lemon"); - containList.add("lime"); - Assert.assertTrue(baseBag.containsAll(containList)); - } - - @Test - public void whenAddtoTreeBag_thenRemove_thenContainsCorrect() { - treeBag.add("banana", 8); - treeBag.add("apple", 2); - treeBag.add("lime"); - - Assert.assertEquals(11, treeBag.size()); - Assert.assertEquals("apple", treeBag.first()); - Assert.assertEquals("lime", treeBag.last()); - - treeBag.remove("apple"); - Assert.assertEquals(9, treeBag.size()); - Assert.assertEquals("banana", treeBag.first()); - - } + + @Test + public void givenMultipleCopies_whenAdded_theCountIsKept() { + Bag bag = new HashBag<>( + Arrays.asList(new Integer[] { 1, 2, 3, 3, 3, 1, 4 })); + + assertThat(bag.getCount(1), equalTo(2)); + } + + @Test + public void givenBag_whenBagAddAPILikeCollectionAPI_thenFalse() { + Collection collection = new ArrayList<>(); + + // Collection contract defines that add() should return true + assertThat(collection.add(9), is(true)); + + // Even when element is already in the collection + collection.add(1); + assertThat(collection.add(1), is(true)); + + Bag bag = new HashBag<>(); + + // Bag returns true on adding a new element + assertThat(bag.add(9), is(true)); + + bag.add(1); + // But breaks the contract with false when it has to increment the count + assertThat(bag.add(1), is(not(true))); + } + + @Test + public void givenDecoratedBag_whenBagAddAPILikeCollectionAPI_thenTrue() { + Bag bag = CollectionBag.collectionBag(new HashBag<>()); + + bag.add(1); + // This time the behavior is compliant to the Java Collection + assertThat(bag.add(1), is((true))); + } + + @Test + public void givenAdd_whenCountOfElementsDefined_thenCountAreAdded() { + Bag bag = new HashBag<>(); + + // Adding 1 for 5 times + bag.add(1, 5); + assertThat(bag.getCount(1), equalTo(5)); + } + + @Test + public void givenMultipleCopies_whenRemove_allAreRemoved() { + Bag bag = new HashBag<>( + Arrays.asList(new Integer[] { 1, 2, 3, 3, 3, 1, 4 })); + + // From 3 we delete 1, 2 remain + bag.remove(3, 1); + assertThat(bag.getCount(3), equalTo(2)); + + // From 2 we delete all + bag.remove(1); + assertThat(bag.getCount(1), equalTo(0)); + } + + @Test + public void givenTree_whenDuplicateElementsAdded_thenSort() { + TreeBag bag = new TreeBag<>( + Arrays.asList(new Integer[] { 7, 5, 1, 7, 2, 3, 3, 3, 1, 4, 7 })); + + assertThat(bag.first(), equalTo(1)); + assertThat(bag.getCount(bag.first()), equalTo(2)); + assertThat(bag.last(), equalTo(7)); + assertThat(bag.getCount(bag.last()), equalTo(3)); + } + + @Test + public void givenDecoratedTree_whenTreeAddAPILikeCollectionAPI_thenTrue() { + SortedBag bag = CollectionSortedBag + .collectionSortedBag(new TreeBag<>()); + + bag.add(1); + assertThat(bag.add(1), is((true))); + } + + @Test + public void givenSortedBag_whenDuplicateElementsAdded_thenSort() { + SynchronizedSortedBag bag = SynchronizedSortedBag + .synchronizedSortedBag(new TreeBag<>( + Arrays.asList(new Integer[] { 7, 5, 1, 7, 2, 3, 3, 3, 1, 4, 7 }))); + + assertThat(bag.first(), equalTo(1)); + assertThat(bag.getCount(bag.first()), equalTo(2)); + assertThat(bag.last(), equalTo(7)); + assertThat(bag.getCount(bag.last()), equalTo(3)); + } } diff --git a/libraries/src/test/java/com/baeldung/commons/io/CommonsIOUnitTest.java b/libraries/src/test/java/com/baeldung/commons/io/CommonsIOUnitTest.java new file mode 100644 index 0000000000..3c82c30d9b --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/io/CommonsIOUnitTest.java @@ -0,0 +1,151 @@ +package com.baeldung.commons.io; + +import org.apache.commons.io.FileSystemUtils; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOCase; +import org.apache.commons.io.comparator.PathFileComparator; +import org.apache.commons.io.comparator.SizeFileComparator; +import org.apache.commons.io.filefilter.AndFileFilter; +import org.apache.commons.io.filefilter.NameFileFilter; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.apache.commons.io.input.TeeInputStream; +import org.apache.commons.io.output.TeeOutputStream; +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.nio.charset.Charset; + +public class CommonsIOUnitTest { + + @Test + public void whenCopyANDReadFileTesttxt_thenMatchExpectedData() + throws IOException { + + String expectedData = "Hello World from fileTest.txt!!!"; + + File file = FileUtils.getFile(getClass().getClassLoader() + .getResource("fileTest.txt") + .getPath()); + File tempDir = FileUtils.getTempDirectory(); + FileUtils.copyFileToDirectory(file, tempDir); + File newTempFile = FileUtils.getFile(tempDir, file.getName()); + String data = FileUtils.readFileToString(newTempFile, + Charset.defaultCharset()); + + Assert.assertEquals(expectedData, data.trim()); + } + + @Test + public void whenUsingFileNameUtils_thenshowdifferentFileOperations() + throws IOException { + + String path = getClass().getClassLoader() + .getResource("fileTest.txt") + .getPath(); + + String fullPath = FilenameUtils.getFullPath(path); + String extension = FilenameUtils.getExtension(path); + String baseName = FilenameUtils.getBaseName(path); + + System.out.println("full path" + fullPath); + System.out.println("Extension" + extension); + System.out.println("Base name" + baseName); + } + + @Test + public void whenUsingFileSystemUtils_thenDriveFreeSpace() + throws IOException { + + long freeSpace = FileSystemUtils.freeSpaceKb("/"); + } + + @SuppressWarnings("resource") + @Test + public void whenUsingTeeInputOutputStream_thenWriteto2OutputStreams() + throws IOException { + + final String str = "Hello World."; + ByteArrayInputStream inputStream = new ByteArrayInputStream(str.getBytes()); + ByteArrayOutputStream outputStream1 = new ByteArrayOutputStream(); + ByteArrayOutputStream outputStream2 = new ByteArrayOutputStream(); + + FilterOutputStream teeOutputStream = new TeeOutputStream(outputStream1,outputStream2); + new TeeInputStream(inputStream, teeOutputStream, true).read(new byte[str.length()]); + + Assert.assertEquals(str, String.valueOf(outputStream1)); + Assert.assertEquals(str, String.valueOf(outputStream2)); + } + + @Test + public void whenGetFilewithNameFileFilter_thenFindfileTesttxt() + throws IOException { + + final String testFile = "fileTest.txt"; + + String path = getClass().getClassLoader() + .getResource(testFile) + .getPath(); + File dir = FileUtils.getFile(FilenameUtils.getFullPath(path)); + + String[] possibleNames = { "NotThisOne", testFile }; + + Assert.assertEquals(testFile, + dir.list(new NameFileFilter(possibleNames, IOCase.INSENSITIVE))[0]); + } + + @Test + public void whenGetFilewith_ANDFileFilter_thenFindsampletxt() + throws IOException { + + String path = getClass().getClassLoader() + .getResource("fileTest.txt") + .getPath(); + File dir = FileUtils.getFile(FilenameUtils.getFullPath(path)); + + Assert.assertEquals("sample.txt", + dir.list(new AndFileFilter( + new WildcardFileFilter("*ple*", IOCase.INSENSITIVE), + new SuffixFileFilter("txt")))[0]); + } + + @Test + public void whenSortDirWithPathFileComparator_thenFirstFileaaatxt() + throws IOException { + + PathFileComparator pathFileComparator = new PathFileComparator( + IOCase.INSENSITIVE); + String path = FilenameUtils.getFullPath(getClass().getClassLoader() + .getResource("fileTest.txt") + .getPath()); + File dir = new File(path); + File[] files = dir.listFiles(); + + pathFileComparator.sort(files); + + Assert.assertEquals("aaa.txt", files[0].getName()); + } + + @Test + public void whenSizeFileComparator_thenLargerFile() + throws IOException { + + SizeFileComparator sizeFileComparator = new SizeFileComparator(); + File largerFile = FileUtils.getFile(getClass().getClassLoader() + .getResource("fileTest.txt") + .getPath()); + File smallerFile = FileUtils.getFile(getClass().getClassLoader() + .getResource("sample.txt") + .getPath()); + + int i = sizeFileComparator.compare(largerFile, smallerFile); + + Assert.assertTrue(i > 0); + } +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsTest.java index 2e74ad3c24..29bcebeb2b 100644 --- a/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsTest.java +++ b/libraries/src/test/java/com/baeldung/commons/lang3/Lang3UtilsTest.java @@ -1,8 +1,11 @@ package com.baeldung.commons.lang3; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -12,12 +15,15 @@ import java.beans.PropertyChangeListener; import java.io.File; import java.lang.reflect.Field; import java.util.Locale; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.apache.commons.lang3.ArchUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.arch.Processor; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.apache.commons.lang3.concurrent.ConcurrentException; import org.apache.commons.lang3.concurrent.ConcurrentRuntimeException; import org.apache.commons.lang3.concurrent.ConcurrentUtils; import org.apache.commons.lang3.event.EventUtils; @@ -97,22 +103,47 @@ public class Lang3UtilsTest { public void testAddEventListenerThrowsException() { final ExceptionEventSource src = new ExceptionEventSource(); try { - EventUtils.addEventListener(src, PropertyChangeListener.class, new PropertyChangeListener() { - @Override - public void propertyChange(final PropertyChangeEvent e) { - // Do nothing! - } - }); + EventUtils.addEventListener(src, PropertyChangeListener.class, (PropertyChangeEvent e) -> { + /* Change event*/}); fail("Add method should have thrown an exception, so method should fail."); } catch (final RuntimeException e) { } } + @Test + public void ConcurrentExceptionSample() throws ConcurrentException { + final Error err = new AssertionError("Test"); + try { + ConcurrentUtils.handleCause(new ExecutionException(err)); + fail("Error not thrown!"); + } catch (final Error e) { + assertEquals("Wrong error", err, e); + } + } + public static class ExceptionEventSource { public void addPropertyChangeListener(final PropertyChangeListener listener) { throw new RuntimeException(); } } + @Test + public void testLazyInitializer() throws Exception { + SampleLazyInitializer sampleLazyInitializer = new SampleLazyInitializer(); + SampleObject sampleObjectOne = sampleLazyInitializer.get(); + SampleObject sampleObjectTwo = sampleLazyInitializer.get(); + assertEquals(sampleObjectOne, sampleObjectTwo); + } + + @Test + public void testBuildDefaults() { + BasicThreadFactory.Builder builder = new BasicThreadFactory.Builder(); + BasicThreadFactory factory = builder.build(); + assertNull("No naming pattern set Yet", factory.getNamingPattern()); + BasicThreadFactory factory2 = builder.namingPattern("sampleNamingPattern").daemon(true).priority(Thread.MIN_PRIORITY).build(); + assertNotNull("Got a naming pattern", factory2.getNamingPattern()); + assertEquals("sampleNamingPattern", factory2.getNamingPattern()); + + } } diff --git a/libraries/src/test/java/com/baeldung/crdt/CRDTTest.java b/libraries/src/test/java/com/baeldung/crdt/CRDTTest.java new file mode 100644 index 0000000000..8309e755ce --- /dev/null +++ b/libraries/src/test/java/com/baeldung/crdt/CRDTTest.java @@ -0,0 +1,153 @@ +package com.baeldung.crdt; + +import com.netopyr.wurmloch.crdt.GCounter; +import com.netopyr.wurmloch.crdt.GSet; +import com.netopyr.wurmloch.crdt.LWWRegister; +import com.netopyr.wurmloch.crdt.PNCounter; +import com.netopyr.wurmloch.store.LocalCrdtStore; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CRDTTest { + + @Test + public void givenGrowOnlySet_whenTwoReplicasDiverge_thenShouldMergeItWithoutAConflict() { + //given + final LocalCrdtStore crdtStore1 = new LocalCrdtStore(); + final LocalCrdtStore crdtStore2 = new LocalCrdtStore(); + crdtStore1.connect(crdtStore2); + + final GSet replica1 = crdtStore1.createGSet("ID_1"); + final GSet replica2 = crdtStore2.findGSet("ID_1").get(); + + //when + replica1.add("apple"); + replica2.add("banana"); + + //then + assertThat(replica1).contains("apple", "banana"); + assertThat(replica2).contains("apple", "banana"); + + //when + crdtStore1.disconnect(crdtStore2); + + replica1.add("strawberry"); + replica2.add("pear"); + + + assertThat(replica1).contains("apple", "banana", "strawberry"); + assertThat(replica2).contains("apple", "banana", "pear"); + + crdtStore1.connect(crdtStore2); + + //then + assertThat(replica1).contains("apple", "banana", "strawberry", "pear"); + assertThat(replica2).contains("apple", "banana", "strawberry", "pear"); + } + + @Test + public void givenIncrementOnlyCounter_whenTwoReplicasDiverge_thenShouldMergeIt() { + //given + final LocalCrdtStore crdtStore1 = new LocalCrdtStore(); + final LocalCrdtStore crdtStore2 = new LocalCrdtStore(); + crdtStore1.connect(crdtStore2); + + final GCounter replica1 = crdtStore1.createGCounter("ID_1"); + final GCounter replica2 = crdtStore2.findGCounter("ID_1").get(); + + //when + replica1.increment(); + replica2.increment(2L); + + //then + assertThat(replica1.get()).isEqualTo(3L); + assertThat(replica2.get()).isEqualTo(3L); + + //when + crdtStore1.disconnect(crdtStore2); + + replica1.increment(3L); + replica2.increment(5L); + + + assertThat(replica1.get()).isEqualTo(6L); + assertThat(replica2.get()).isEqualTo(8L); + + crdtStore1.connect(crdtStore2); + + // then + assertThat(replica1.get()).isEqualTo(11L); + assertThat(replica2.get()).isEqualTo(11L); + } + + @Test + public void givenPNCounter_whenReplicasDiverge_thenShouldMergeWithoutAConflict() { + // given + final LocalCrdtStore crdtStore1 = new LocalCrdtStore(); + final LocalCrdtStore crdtStore2 = new LocalCrdtStore(); + crdtStore1.connect(crdtStore2); + + final PNCounter replica1 = crdtStore1.createPNCounter("ID_1"); + final PNCounter replica2 = crdtStore2.findPNCounter("ID_1").get(); + + //when + replica1.increment(); + replica2.decrement(2L); + + //then + assertThat(replica1.get()).isEqualTo(-1L); + assertThat(replica2.get()).isEqualTo(-1L); + + //when + crdtStore1.disconnect(crdtStore2); + + replica1.decrement(3L); + replica2.increment(5L); + + assertThat(replica1.get()).isEqualTo(-4L); + assertThat(replica2.get()).isEqualTo(4L); + + crdtStore1.connect(crdtStore2); + + //then + assertThat(replica1.get()).isEqualTo(1L); + assertThat(replica2.get()).isEqualTo(1L); + } + + @Test + public void givenLastWriteWinsStrategy_whenReplicasDiverge_thenAfterMergeShouldKeepOnlyLastValue() { + //given + final LocalCrdtStore crdtStore1 = new LocalCrdtStore("N_1"); + final LocalCrdtStore crdtStore2 = new LocalCrdtStore("N_2"); + crdtStore1.connect(crdtStore2); + + final LWWRegister replica1 = crdtStore1.createLWWRegister("ID_1"); + final LWWRegister replica2 = crdtStore2.findLWWRegister("ID_1").get(); + + //when + replica1.set("apple"); + replica2.set("banana"); + + // then + assertThat(replica1.get()).isEqualTo("banana"); + assertThat(replica2.get()).isEqualTo("banana"); + + + // when + crdtStore1.disconnect(crdtStore2); + + replica1.set("strawberry"); + replica2.set("pear"); + + + assertThat(replica1.get()).isEqualTo("strawberry"); + assertThat(replica2.get()).isEqualTo("pear"); + + crdtStore1.connect(crdtStore2); + + //then + assertThat(replica1.get()).isEqualTo("pear"); + assertThat(replica2.get()).isEqualTo("pear"); + } +} diff --git a/libraries/src/test/java/com/baeldung/docx/Docx4jReadAndWriteTest.java b/libraries/src/test/java/com/baeldung/docx/Docx4jReadAndWriteTest.java new file mode 100644 index 0000000000..7c3f779931 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/docx/Docx4jReadAndWriteTest.java @@ -0,0 +1,19 @@ +package com.baeldung.docx; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class Docx4jReadAndWriteTest { + + private static final String imagePath = "src/main/resources/image.jpg"; + private static final String outputPath = "helloWorld.docx"; + + @Test + public void givenWordPackage_whenTextExist_thenReturnTrue() throws Exception { + Docx4jExample docx4j = new Docx4jExample(); + docx4j.createDocumentPackage(outputPath, imagePath); + assertTrue(docx4j.isTextExist("Hello World!")); + assertTrue(!docx4j.isTextExist("InexistantText")); + } +} diff --git a/libraries/src/test/java/com/baeldung/fj/FunctionalJavaTest.java b/libraries/src/test/java/com/baeldung/fj/FunctionalJavaTest.java new file mode 100644 index 0000000000..04ab6e43be --- /dev/null +++ b/libraries/src/test/java/com/baeldung/fj/FunctionalJavaTest.java @@ -0,0 +1,79 @@ +package com.baeldung.fj; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import fj.F; +import fj.data.Array; +import fj.data.List; +import fj.data.Option; +import fj.function.Characters; +import fj.function.Integers; + +public class FunctionalJavaTest { + + public static final F isEven = i -> i % 2 == 0; + + @Test + public void calculateEvenNumbers_givenIntList_returnTrue() { + List fList = List.list(3, 4, 5, 6); + List evenList = fList.map(isEven); + List evenListTrueResult = List.list(false, true, false, true); + List evenListFalseResult = List.list(true, false, false, true); + assertEquals(evenList.equals(evenListTrueResult), true); + assertEquals(evenList.equals(evenListFalseResult), false); + } + + @Test + public void mapList_givenIntList_returnResult() { + List fList = List.list(3, 4, 5, 6); + fList = fList.map(i -> i + 100); + List resultList = List.list(103, 104, 105, 106); + List falseResultList = List.list(15, 504, 105, 106); + assertEquals(fList.equals(resultList), true); + assertEquals(fList.equals(falseResultList), false); + } + + @Test + public void filterList_givenIntList_returnResult() { + Array array = Array.array(3, 4, 5, 6); + Array filteredArray = array.filter(Integers.even); + Array result = Array.array(4, 6); + Array wrongResult = Array.array(3, 5); + assertEquals(filteredArray.equals(result), true); + assertEquals(filteredArray.equals(wrongResult), false); + } + + @Test + public void checkForLowerCase_givenStringArray_returnResult() { + Array array = Array.array("Welcome", "To", "baeldung"); + Array array2 = Array.array("Welcome", "To", "Baeldung"); + Boolean isExist = array.exists(s -> List.fromString(s).forall(Characters.isLowerCase)); + Boolean isExist2 = array2.exists(s -> List.fromString(s).forall(Characters.isLowerCase)); + assertEquals(isExist, true); + assertEquals(isExist2, false); + } + + @Test + public void checkOptions_givenOptions_returnResult() { + Option n1 = Option.some(1); + Option n2 = Option.some(2); + + F> f1 = i -> i % 2 == 0 ? Option.some(i + 100) : Option.none(); + + Option result1 = n1.bind(f1); + Option result2 = n2.bind(f1); + + assertEquals(result1, Option.none()); + assertEquals(result2, Option.some(102)); + } + + @Test + public void foldLeft_givenArray_returnResult() { + Array intArray = Array.array(17, 44, 67, 2, 22, 80, 1, 27); + int sum = intArray.foldLeft(Integers.add, 0); + assertEquals(sum, 260); + } + +} diff --git a/libraries/src/test/java/com/baeldung/javax/measure/WaterTankTests.java b/libraries/src/test/java/com/baeldung/javax/measure/WaterTankTests.java deleted file mode 100644 index ef54035353..0000000000 --- a/libraries/src/test/java/com/baeldung/javax/measure/WaterTankTests.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.baeldung.javax.measure; - -import javax.measure.Measure; -import javax.measure.converter.UnitConverter; -import javax.measure.quantity.Duration; -import javax.measure.quantity.Length; -import javax.measure.quantity.Pressure; -import javax.measure.quantity.Volume; -import static javax.measure.unit.NonSI.HOUR; -import static javax.measure.unit.NonSI.LITRE; -import static javax.measure.unit.NonSI.MILE; -import static javax.measure.unit.NonSI.MINUTE; -import javax.measure.unit.SI; -import static javax.measure.unit.SI.KILO; -import static javax.measure.unit.SI.METER; -import static javax.measure.unit.SI.NEWTON; -import static javax.measure.unit.SI.SECOND; -import javax.measure.unit.Unit; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import org.junit.Test; - -public class WaterTankTests { - - @Test - public void givenMeasure_whenGetUnitAndConvertValue_thenSuccess() { - WaterTank waterTank = new WaterTank(); - waterTank.setCapacityMeasure(Measure.valueOf(9.2, LITRE)); - assertEquals(LITRE, waterTank.getCapacityMeasure().getUnit()); - - Measure waterCapacity = waterTank.getCapacityMeasure(); - double volumeInLitre = waterCapacity.getValue().doubleValue(); - assertEquals(9.2, volumeInLitre, 0.0f); - - double volumeInMilliLitre = waterCapacity.doubleValue(SI.MILLI(LITRE)); - assertEquals(9200.0, volumeInMilliLitre, 0.0f); - - Unit Kilometer = SI.KILO(METER); - Unit Centimeter = SI.CENTI(METER); - } - - @Test - public void givenMeasure_whenAlternateMeasure_ThenGetAlternateMeasure() { - Unit PASCAL = NEWTON.divide(METER.pow(2)).alternate("Pa"); - assertTrue(Unit.valueOf("Pa").equals(PASCAL)); - } - - @Test - public void givenMeasure_whenCompoundMeasure_ThenGetCompoundMeasure() { - Unit HOUR_MINUTE_SECOND = HOUR.compound(MINUTE).compound(SECOND); - Measure duration = Measure.valueOf(12345, SECOND); - assertEquals("3h25min45s", duration.to(HOUR_MINUTE_SECOND).toString()); - } - - @Test - public void givenMiles_whenConvertToKilometer_ThenConverted() { - double distanceInMiles = 50.0; - UnitConverter mileToKilometer = MILE.getConverterTo(KILO(METER)); - double distanceInKilometers = mileToKilometer.convert(distanceInMiles); - assertEquals(80.4672, distanceInKilometers, 0.00f); - } - - @Test - public void givenSymbol_WhenCompareToSystemUnit_ThenSuccess() { - assertTrue(Unit.valueOf("kW").equals(SI.KILO(SI.WATT))); - assertTrue(Unit.valueOf("ms").equals(SI.SECOND.divide(1000))); - } -} diff --git a/libraries/src/test/java/com/baeldung/jcache/CacheLoaderTest.java b/libraries/src/test/java/com/baeldung/jcache/CacheLoaderTest.java new file mode 100644 index 0000000000..da4f51674f --- /dev/null +++ b/libraries/src/test/java/com/baeldung/jcache/CacheLoaderTest.java @@ -0,0 +1,44 @@ +package com.baeldung.jcache; + +import static org.junit.Assert.assertEquals; + +import javax.cache.Cache; +import javax.cache.CacheManager; +import javax.cache.Caching; +import javax.cache.configuration.FactoryBuilder; +import javax.cache.configuration.MutableConfiguration; +import javax.cache.spi.CachingProvider; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class CacheLoaderTest { + + private static final String CACHE_NAME = "SimpleCache"; + + private Cache cache; + + @Before + public void setup() { + CachingProvider cachingProvider = Caching.getCachingProvider(); + CacheManager cacheManager = cachingProvider.getCacheManager(); + MutableConfiguration config = new MutableConfiguration().setReadThrough(true) + .setCacheLoaderFactory(new FactoryBuilder.SingletonFactory<>(new SimpleCacheLoader())); + this.cache = cacheManager.createCache("SimpleCache", config); + } + + @After + public void tearDown() { + Caching.getCachingProvider() + .getCacheManager().destroyCache(CACHE_NAME); + } + + @Test + public void whenReadingFromStorage_thenCorrect() { + for (int i = 1; i < 4; i++) { + String value = cache.get(i); + assertEquals("fromCache" + i, value); + } + } +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/jcache/EntryProcessorTest.java b/libraries/src/test/java/com/baeldung/jcache/EntryProcessorTest.java new file mode 100644 index 0000000000..eb40e63ef0 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/jcache/EntryProcessorTest.java @@ -0,0 +1,41 @@ +package com.baeldung.jcache; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.cache.Cache; +import javax.cache.CacheManager; +import javax.cache.Caching; +import javax.cache.configuration.MutableConfiguration; +import javax.cache.spi.CachingProvider; + +import static org.junit.Assert.assertEquals; + +public class EntryProcessorTest { + + private static final String CACHE_NAME = "MyCache"; + + private Cache cache; + + @Before + public void instantiateCache() { + CachingProvider cachingProvider = Caching.getCachingProvider(); + CacheManager cacheManager = cachingProvider.getCacheManager(); + MutableConfiguration config = new MutableConfiguration<>(); + this.cache = cacheManager.createCache(CACHE_NAME, config); + this.cache.put("key", "value"); + } + + @After + public void tearDown() { + Caching.getCachingProvider() + .getCacheManager().destroyCache(CACHE_NAME); + } + + @Test + public void whenModifyValue_thenCorrect() { + this.cache.invoke("key", new SimpleEntryProcessor()); + assertEquals("value - modified", cache.get("key")); + } +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/jcache/EventListenerTest.java b/libraries/src/test/java/com/baeldung/jcache/EventListenerTest.java new file mode 100644 index 0000000000..be83e572d8 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/jcache/EventListenerTest.java @@ -0,0 +1,56 @@ +package com.baeldung.jcache; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.cache.Cache; +import javax.cache.CacheManager; +import javax.cache.Caching; +import javax.cache.configuration.FactoryBuilder; +import javax.cache.configuration.MutableCacheEntryListenerConfiguration; +import javax.cache.configuration.MutableConfiguration; +import javax.cache.spi.CachingProvider; + +import static org.junit.Assert.assertEquals; + +public class EventListenerTest { + + private static final String CACHE_NAME = "MyCache"; + + private Cache cache; + private SimpleCacheEntryListener listener; + private MutableCacheEntryListenerConfiguration listenerConfiguration; + + @Before + public void setup() { + CachingProvider cachingProvider = Caching.getCachingProvider(); + CacheManager cacheManager = cachingProvider.getCacheManager(); + MutableConfiguration config = new MutableConfiguration(); + this.cache = cacheManager.createCache("MyCache", config); + this.listener = new SimpleCacheEntryListener(); + } + + @After + public void tearDown() { + Caching.getCachingProvider() + .getCacheManager().destroyCache(CACHE_NAME); + } + + @Test + public void whenRunEvent_thenCorrect() throws InterruptedException { + this.listenerConfiguration = new MutableCacheEntryListenerConfiguration<>(FactoryBuilder + .factoryOf(this.listener), null, false, true); + this.cache.registerCacheEntryListener(this.listenerConfiguration); + + assertEquals(false, this.listener.getCreated()); + + this.cache.put("key", "value"); + assertEquals(true, this.listener.getCreated()); + assertEquals(false, this.listener.getUpdated()); + + this.cache.put("key", "newValue"); + assertEquals(true, this.listener.getUpdated()); + } + +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/jcache/JCacheTest.java b/libraries/src/test/java/com/baeldung/jcache/JCacheTest.java new file mode 100644 index 0000000000..c98539a9ec --- /dev/null +++ b/libraries/src/test/java/com/baeldung/jcache/JCacheTest.java @@ -0,0 +1,27 @@ +package com.baeldung.jcache; + +import org.junit.Test; + +import javax.cache.Cache; +import javax.cache.CacheManager; +import javax.cache.Caching; +import javax.cache.configuration.MutableConfiguration; +import javax.cache.spi.CachingProvider; + +import static org.junit.Assert.assertEquals; + +public class JCacheTest { + + @Test + public void instantiateCache() { + CachingProvider cachingProvider = Caching.getCachingProvider(); + CacheManager cacheManager = cachingProvider.getCacheManager(); + MutableConfiguration config = new MutableConfiguration<>(); + Cache cache = cacheManager.createCache("simpleCache", config); + cache.put("key1", "value1"); + cache.put("key2", "value2"); + assertEquals("value1", cache.get("key1")); + assertEquals("value2", cache.get("key2")); + cacheManager.close(); + } +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/jdeffered/AppTest.java b/libraries/src/test/java/com/baeldung/jdeffered/AppTest.java index b48c9c2652..97b20cda57 100644 --- a/libraries/src/test/java/com/baeldung/jdeffered/AppTest.java +++ b/libraries/src/test/java/com/baeldung/jdeffered/AppTest.java @@ -1,8 +1,7 @@ package com.baeldung.jdeffered; -import org.junit.Test; - import com.baeldung.jdeffered.PipeDemo.Result; +import org.junit.Test; import static org.junit.Assert.assertEquals; @@ -24,5 +23,4 @@ public class AppTest { Result result = PipeDemo.validate(80); assertEquals(result, Result.SUCCESS); } - } diff --git a/libraries/src/test/java/com/baeldung/jetty/JettyIntegrationTest.java b/libraries/src/test/java/com/baeldung/jetty/JettyIntegrationTest.java index 151bcc78a2..28d4f57e77 100644 --- a/libraries/src/test/java/com/baeldung/jetty/JettyIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/jetty/JettyIntegrationTest.java @@ -7,7 +7,9 @@ import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClientBuilder; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import java.nio.charset.StandardCharsets; @@ -15,17 +17,16 @@ import java.nio.charset.StandardCharsets; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; public class JettyIntegrationTest { - private JettyServer jettyServer; + private static JettyServer jettyServer; - @Before - public void setup() throws Exception { + @BeforeClass + public static void setup() throws Exception { jettyServer = new JettyServer(); jettyServer.start(); } - @After - public void cleanup() throws Exception { - Thread.sleep(2000); + @AfterClass + public static void cleanup() throws Exception { jettyServer.stop(); } diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchTest.java index a0648aa4e1..0cab612a7b 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncDispatchTest.java @@ -13,7 +13,7 @@ import static org.junit.Assert.assertNotNull; public class MBassadorAsyncDispatchTest { - private MBassador dispatcher = new MBassador(); + private MBassador dispatcher = new MBassador(); private String testString; private AtomicBoolean ready = new AtomicBoolean(false); diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationTest.java index d20c887309..d0b1cafd71 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorAsyncInvocationTest.java @@ -17,7 +17,7 @@ import static org.junit.Assert.assertFalse; public class MBassadorAsyncInvocationTest { - private MBassador dispatcher = new MBassador(); + private MBassador dispatcher = new MBassador(); private Integer testInteger; private String invocationThreadName; diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationTest.java index d1e711999c..fe9c130d93 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorConfigurationTest.java @@ -24,8 +24,9 @@ public class MBassadorConfigurationTest implements IPublicationErrorHandler { @Before public void prepareTests() { - dispatcher = new MBassador(this); - dispatcher.subscribe(this); + + dispatcher = new MBassador(this); + dispatcher.subscribe(this); } @Test diff --git a/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyTest.java b/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyTest.java index 87d6a621a4..be5c9d4897 100644 --- a/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyTest.java +++ b/libraries/src/test/java/com/baeldung/mbassador/MBassadorHierarchyTest.java @@ -9,7 +9,7 @@ import static org.junit.Assert.*; public class MBassadorHierarchyTest { - private MBassador dispatcher = new MBassador(); + private MBassador dispatcher = new MBassador(); private Message message; private AckMessage ackMessage; diff --git a/libraries/src/test/java/com/baeldung/measurement/WaterTankTests.java b/libraries/src/test/java/com/baeldung/measurement/WaterTankTests.java new file mode 100644 index 0000000000..b023ffe8d9 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/measurement/WaterTankTests.java @@ -0,0 +1,86 @@ +package com.baeldung.measurement; + +import javax.measure.Quantity; +import javax.measure.quantity.Area; +import javax.measure.quantity.Length; +import javax.measure.quantity.Pressure; +import javax.measure.quantity.Volume; + +import javax.measure.Unit; +import javax.measure.UnitConverter; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +import com.baeldung.measurement.WaterTank; + +import tec.units.ri.format.SimpleUnitFormat; +import tec.units.ri.quantity.Quantities; +import tec.units.ri.unit.MetricPrefix; +import static tec.units.ri.unit.Units.*; + +public class WaterTankTests { + + @Test + public void givenQuantity_whenGetUnitAndConvertValue_thenSuccess() { + WaterTank waterTank = new WaterTank(); + waterTank.setCapacityMeasure(Quantities.getQuantity(9.2, LITRE)); + assertEquals(LITRE, waterTank.getCapacityMeasure().getUnit()); + + Quantity waterCapacity = waterTank.getCapacityMeasure(); + double volumeInLitre = waterCapacity.getValue().doubleValue(); + assertEquals(9.2, volumeInLitre, 0.0f); + + double volumeInMilliLitre = waterCapacity.to(MetricPrefix.MILLI(LITRE)).getValue().doubleValue(); + assertEquals(9200.0, volumeInMilliLitre, 0.0f); + + // compilation error + // volumeInMilliLitre = waterCapacity.to(MetricPrefix.MILLI(KILOGRAM)); + + Unit Kilometer = MetricPrefix.KILO(METRE); + + // compilation error + // Unit Centimeter = MetricPrefix.CENTI(LITRE); + } + + @Test + public void givenUnit_whenAlternateUnit_ThenGetAlternateUnit() { + + Unit PASCAL = NEWTON.divide(METRE.pow(2)).alternate("Pa").asType(Pressure.class); + assertTrue(SimpleUnitFormat.getInstance().parse("Pa").equals(PASCAL)); + } + + @Test + public void givenUnit_whenProduct_ThenGetProductUnit() { + Unit squareMetre = METRE.multiply(METRE).asType(Area.class); + Quantity line = Quantities.getQuantity(2, METRE); + assertEquals(line.multiply(line).getUnit(), squareMetre); + } + + @Test + public void givenMeters_whenConvertToKilometer_ThenConverted() { + double distanceInMeters = 50.0; + UnitConverter metreToKilometre = METRE.getConverterTo(MetricPrefix.KILO(METRE)); + double distanceInKilometers = metreToKilometre.convert(distanceInMeters); + assertEquals(0.05, distanceInKilometers, 0.00f); + } + + @Test + public void givenSymbol_WhenCompareToSystemUnit_ThenSuccess() { + assertTrue(SimpleUnitFormat.getInstance().parse("kW").equals(MetricPrefix.KILO(WATT))); + assertTrue(SimpleUnitFormat.getInstance().parse("ms").equals(SECOND.divide(1000))); + } + + @Test + public void givenUnits_WhenAdd_ThenSuccess() { + Quantity total = Quantities.getQuantity(2, METRE).add(Quantities.getQuantity(3, METRE)); + assertEquals(total.getValue().intValue(), 5); + + // compilation error + // Quantity total = Quantities.getQuantity(2, METRE).add(Quantities.getQuantity(3, LITRE)); + + Quantity totalKm = Quantities.getQuantity(2, METRE).add(Quantities.getQuantity(3, MetricPrefix.KILO(METRE))); + assertEquals(totalKm.getValue().intValue(), 3002); + } +} diff --git a/libraries/src/test/java/com/baeldung/pairs/ApacheCommonsPairUnitTest.java b/libraries/src/test/java/com/baeldung/pairs/ApacheCommonsPairUnitTest.java new file mode 100644 index 0000000000..0e6242b8a3 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/pairs/ApacheCommonsPairUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.pairs; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.MutablePair; +import org.junit.Assert; +import org.junit.Test; + +public class ApacheCommonsPairUnitTest { + + @Test + public void givenMutablePair_whenGetValue_shouldPass() { + int key = 5; + String value = "Five"; + + MutablePair mutablePair = new MutablePair<>(key, value); + Assert.assertTrue(mutablePair.getKey() == key); + Assert.assertEquals(mutablePair.getValue(), value); + } + + @Test + public void givenMutablePair_whenSetValue_shouldPass() { + int key = 6; + String value = "Six"; + String newValue = "New Six"; + + MutablePair mutablePair = new MutablePair<>(key, value); + Assert.assertTrue(mutablePair.getKey() == key); + Assert.assertEquals(mutablePair.getValue(), value); + mutablePair.setValue(newValue); + Assert.assertEquals(mutablePair.getValue(), newValue); + } + + @Test + public void givenImmutablePair_whenGetValue_shouldPass() { + int key = 2; + String value = "Two"; + + ImmutablePair immutablePair = new ImmutablePair<>(key, value); + Assert.assertTrue(immutablePair.getKey() == key); + Assert.assertEquals(immutablePair.getValue(), value); + } + + @Test(expected = UnsupportedOperationException.class) + public void givenImmutablePair_whenSetValue_shouldFail() { + ImmutablePair immutablePair = new ImmutablePair<>(1, "One"); + immutablePair.setValue("Another One"); + } + + +} diff --git a/libraries/src/test/java/com/baeldung/pairs/CoreJavaPairUnitTest.java b/libraries/src/test/java/com/baeldung/pairs/CoreJavaPairUnitTest.java new file mode 100644 index 0000000000..ac258b9c77 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/pairs/CoreJavaPairUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.pairs; + +import javafx.util.Pair; +import org.junit.Assert; +import org.junit.Test; + +public class CoreJavaPairUnitTest { + @Test + public void givenPair_whenGetValue_shouldSucceed() { + String key = "Good Day"; + boolean value = true; + Pair pair = new Pair<>(key, value); + + Assert.assertEquals(key, pair.getKey()); + Assert.assertEquals(value, pair.getValue()); + } +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/pairs/CoreJavaSimpleEntryUnitTest.java b/libraries/src/test/java/com/baeldung/pairs/CoreJavaSimpleEntryUnitTest.java new file mode 100644 index 0000000000..ca425339fa --- /dev/null +++ b/libraries/src/test/java/com/baeldung/pairs/CoreJavaSimpleEntryUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.pairs; + +import static org.junit.Assert.*; + +import java.util.AbstractMap; + +import org.junit.Test; + +public class CoreJavaSimpleEntryUnitTest { + + @Test + public void givenSimpleEntry_whenGetValue_thenOk() { + AbstractMap.SimpleEntry entry = new AbstractMap.SimpleEntry(1, "one"); + Integer key = entry.getKey(); + String value = entry.getValue(); + + assertEquals(key.intValue(), 1); + assertEquals(value, "one"); + } + + @Test(expected = UnsupportedOperationException.class) + public void givenSimpleImmutableEntry_whenSetValue_thenException() { + AbstractMap.SimpleImmutableEntry entry = new AbstractMap.SimpleImmutableEntry(1, "one"); + + entry.setValue("two"); + + } + + @Test + public void givenSimpleImmutableEntry_whenGetValue_thenOk() { + AbstractMap.SimpleImmutableEntry entry = new AbstractMap.SimpleImmutableEntry(1, "one"); + Integer key = entry.getKey(); + String value = entry.getValue(); + + assertEquals(key.intValue(), 1); + assertEquals(value, "one"); + } + +} diff --git a/libraries/src/test/java/com/baeldung/pairs/VavrPairsUnitTest.java b/libraries/src/test/java/com/baeldung/pairs/VavrPairsUnitTest.java new file mode 100644 index 0000000000..9c318c7744 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/pairs/VavrPairsUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.pairs; + +import io.vavr.Tuple2; +import org.junit.Assert; +import org.junit.Test; + +public class VavrPairsUnitTest { + @Test + public void givenTuple_whenSetValue_shouldSucceed() { + String key = "Eleven"; + double value = 11.0; + double newValue = 11.1; + + Tuple2 pair = new Tuple2<>(key, value); + + pair = pair.update2(newValue); + Assert.assertTrue(newValue == pair._2()); + } + + @Test + public void givenPair_whenGetValue_shouldSucceed() { + String key = "Twelve"; + double value = 12.0; + + Tuple2 pair = new Tuple2<>(key, value); + + Assert.assertTrue(value == pair._2()); + } +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsTests.java b/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsTests.java index 4fd21ec508..cf6a1e5ec5 100644 --- a/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsTests.java +++ b/libraries/src/test/java/com/baeldung/protonpack/CollectorUtilsTests.java @@ -16,7 +16,7 @@ import static org.hamcrest.MatcherAssert.assertThat; public class CollectorUtilsTests { @Test - public void maxByWithProjectionAndDefaultComparer() { + public void givenIntegerStream_whenCollectOnMaxByProjection_shouldReturnOptionalMaxValue() { Stream integerStream = Stream.of("a", "bb", "ccc", "1"); Optional max = integerStream.collect(maxBy(String::length)); @@ -25,7 +25,7 @@ public class CollectorUtilsTests { } @Test - public void minByWithProjectionAndDefaultComparer() { + public void givenIntegerStream_whenCollectOnMinByProjection_shouldReturnOptionalMinValue() { Stream integerStream = Stream.of("abc", "bb", "ccc", "1"); Optional max = integerStream.collect(minBy(String::length)); @@ -34,14 +34,14 @@ public class CollectorUtilsTests { } @Test - public void returnsEmptyForEmptyStream() { + public void givenEmptyStream_withCollectorUnique_shouldReturnEmpty() { assertThat(Stream .empty() .collect(CollectorUtils.unique()), equalTo(Optional.empty())); } @Test - public void returnsUniqueItem() { + public void givenIntegerStream_withCollectorUnique_shouldReturnUniqueValue() { assertThat(Stream .of(1, 2, 3) .filter(i -> i > 2) @@ -49,7 +49,7 @@ public class CollectorUtilsTests { } @Test - public void returnsUniqueNullableItem() { + public void givenIntegerStream_withUniqueNullable_shouldReturnUniqueValue() { assertThat(Stream .of(1, 2, 3) .filter(i -> i > 2) @@ -57,7 +57,7 @@ public class CollectorUtilsTests { } @Test(expected = NonUniqueValueException.class) - public void throwsExceptionIfItemIsNotUnique() { + public void givenIntegerStream_withCollectorUnique_shouldThrowNonUniqueValueException() { Stream .of(1, 2, 3) .filter(i -> i > 1) diff --git a/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsTests.java b/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsTests.java index 282a41e0df..37ca71287f 100644 --- a/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsTests.java +++ b/libraries/src/test/java/com/baeldung/protonpack/StreamUtilsTests.java @@ -21,15 +21,7 @@ import static org.hamcrest.Matchers.*; public class StreamUtilsTests { @Test - public void createInfiniteIndex() { - LongStream indices = StreamUtils - .indices() - .limit(500); - - } - - @Test - public void zipAStreamWithIndex() { + public void givenStream_whenZipWithIndex_shouldReturnZippedStreamWithIndex() { Stream source = Stream.of("Foo", "Bar", "Baz"); List> zipped = StreamUtils @@ -40,7 +32,7 @@ public class StreamUtilsTests { } @Test - public void zipAPairOfStreams() { + public void givenTwoStreams_whenZip_shouldReturnZippedStream() { Stream streamA = Stream.of("A", "B", "C"); Stream streamB = Stream.of("Apple", "Banana", "Carrot"); @@ -52,7 +44,7 @@ public class StreamUtilsTests { } @Test - public void zipThreeStreams() { + public void givenThreeStreams_whenZip_shouldReturnZippedStream() { Stream streamA = Stream.of("A", "B", "C"); Stream streamB = Stream.of("aggravating", "banausic", "complaisant"); Stream streamC = Stream.of("Apple", "Banana", "Carrot"); @@ -65,7 +57,8 @@ public class StreamUtilsTests { } @Test - public void mergeThreeStreams() { + //givenThreeStreams_whenMerge_shouldReturnMergedStream + public void givenThreeStreams_whenMerge_shouldReturnMergedStream() { Stream streamA = Stream.of("A", "B", "C"); Stream streamB = Stream.of("apple", "banana", "carrot", "date"); Stream streamC = Stream.of("fritter", "split", "cake", "roll", "pastry"); @@ -76,7 +69,8 @@ public class StreamUtilsTests { } @Test - public void roundRobinInterleaving() { + //givenThreeStreams_whenInterleave_shouldReturnRoundRobinInterleavingStream + public void givenThreeStreams_whenInterleave_shouldReturnRoundRobinInterleavingStream() { Stream streamA = Stream.of("Peter", "Paul", "Mary"); Stream streamB = Stream.of("A", "B", "C", "D", "E"); Stream streamC = Stream.of("foo", "bar", "baz", "xyzzy"); @@ -87,7 +81,8 @@ public class StreamUtilsTests { } @Test - public void takeWhileConditionIsMet() { + //givenInfiniteStream_whenTakeWhile10_shouldReturnStreamOfSize10 + public void givenInfiniteStream_whenTakeWhile10_shouldReturnStream() { Stream infiniteInts = Stream.iterate(0, i -> i + 1); Stream finiteInts = StreamUtils.takeWhile(infiniteInts, i -> i < 10); @@ -95,7 +90,7 @@ public class StreamUtilsTests { } @Test - public void takeUntilConditionIsNotMet() { + public void givenInfiniteStream_whenTakeUntil10_shouldReturnStreamUpto10() { Stream infiniteInts = Stream.iterate(0, i -> i + 1); Stream finiteInts = StreamUtils.takeUntil(infiniteInts, i -> i > 10); @@ -103,7 +98,7 @@ public class StreamUtilsTests { } @Test - public void skipWhileConditionMet() { + public void givenIntegerStreamOfTen_whenSkipWhileLessThanFour_shouldReturnStreamFromFourToTen() { Stream ints = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Stream skipped = StreamUtils.skipWhile(ints, i -> i < 4); List collected = skipped.collect(Collectors.toList()); @@ -112,7 +107,7 @@ public class StreamUtilsTests { } @Test - public void skipUntilConditionMet() { + public void givenIntegerStreamOfTen_whenSkipUntilFour_shouldReturnStreamFromFiveToTen() { Stream ints = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Stream skipped = StreamUtils.skipUntil(ints, i -> i > 4); List collected = skipped.collect(Collectors.toList()); @@ -121,14 +116,14 @@ public class StreamUtilsTests { } @Test - public void unfoldUntilEmptyIsReturned() { + public void givenSeedValue_withUnfold_shouldReturnStreamAccordingToGeneratorMethod() { Stream unfolded = StreamUtils.unfold(1, i -> (i < 10) ? Optional.of(i + 1) : Optional.empty()); assertThat(unfolded.collect(Collectors.toList()), contains(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); } @Test - public void groupRunsStreamTest() { + public void giveIntegerStream_whenGroupRuns_shouldReturnListGroupItems() { Stream integerStream = Stream.of(1, 1, 2, 2, 3, 4, 5); List> runs = StreamUtils .groupRuns(integerStream) @@ -138,14 +133,14 @@ public class StreamUtilsTests { } @Test - public void aggreagateOnBiElementPredicate() { + public void givenAStream_whenAggregate_shouldReturnAggregatedStreamOnTheBasisOfBiFunction() { Stream stream = Stream.of("a1", "b1", "b2", "c1"); Stream> aggregated = StreamUtils.aggregate(stream, (e1, e2) -> e1.charAt(0) == e2.charAt(0)); assertThat(aggregated.collect(toList()), contains(asList("a1"), asList("b1", "b2"), asList("c1"))); } @Test - public void windowingOnList() { + public void givenIntegerStream_whenWindowed_shouldReturnListOfListOfItemsOfWindowSize() { Stream integerStream = Stream.of(1, 2, 3, 4, 5); List> windows = StreamUtils @@ -156,7 +151,8 @@ public class StreamUtilsTests { } @Test - public void windowingOnListTwoOverlap() { + //givenIntegerStream_whenWindowedWithWindowSizeAndSkip_shouldReturnListOfListOfWindowSizeAddingASkip + public void givenIntegerStream_whenWindowedWithWindowSizeAndSkip_shouldReturnListOfListOfWindowSizeAddingASkip() { Stream integerStream = Stream.of(1, 2, 3, 4, 5); List> windows = StreamUtils @@ -167,7 +163,7 @@ public class StreamUtilsTests { } @Test - public void windowingOnEmptyList() { + public void givenEmptyStream_whenWindowed_shouldReturnIterableWithSizeZero() { ArrayList ints = new ArrayList<>(); ints @@ -184,7 +180,7 @@ public class StreamUtilsTests { } @Test - public void windowingOnListTwoOverlapAllowLesserSize() { + public void givenIntegerStream_whenWindowedWithWindowSizeAndSkipAndAllowLesserSize_shouldReturnListOfListOfInteger() { Stream integerStream = Stream.of(1, 2, 3, 4, 5); List> windows = StreamUtils @@ -195,14 +191,12 @@ public class StreamUtilsTests { } @Test - public void windowingOnListOneOverlapAllowLesserSizeMultipleLesserWindows() { - Stream integerStream = Stream.of(1, 2, 3, 4, 5); + public void givenLimit_withIndices_shouldReturnLongStreamUptoLimit() { + LongStream indices = StreamUtils + .indices() + .limit(500); - List> windows = StreamUtils - .windowed(integerStream, 3, 1, true) - .collect(toList()); - - assertThat(windows, contains(asList(1, 2, 3), asList(2, 3, 4), asList(3, 4, 5), asList(4, 5), asList(5))); + assertThat(indices.count(), equalTo(500)); } } diff --git a/libraries/src/test/java/com/baeldung/retrofit/basic/GitHubBasicApiTest.java b/libraries/src/test/java/com/baeldung/retrofit/basic/GitHubBasicApiLiveTest.java similarity index 97% rename from libraries/src/test/java/com/baeldung/retrofit/basic/GitHubBasicApiTest.java rename to libraries/src/test/java/com/baeldung/retrofit/basic/GitHubBasicApiLiveTest.java index da554a551f..7170d35aa5 100644 --- a/libraries/src/test/java/com/baeldung/retrofit/basic/GitHubBasicApiTest.java +++ b/libraries/src/test/java/com/baeldung/retrofit/basic/GitHubBasicApiLiveTest.java @@ -16,7 +16,7 @@ import com.baeldung.retrofit.models.Repository; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; -public class GitHubBasicApiTest { +public class GitHubBasicApiLiveTest { GitHubBasicApi gitHub; diff --git a/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java index 18488f9380..e95b63aa96 100644 --- a/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/serenity/MemberStatusIntegrationTest.java @@ -51,7 +51,6 @@ public class MemberStatusIntegrationTest { /** * This test should fail, comment out @Ignore to see how failed test can be reflected in Serenity report.
    - * Remember to add <testFailureIgnore>true</testFailureIgnore> under maven-surefire-plugin configuration. */ @Test @Ignore diff --git a/libraries/src/test/resources/ABC.txt b/libraries/src/test/resources/ABC.txt new file mode 100644 index 0000000000..f78e42598c --- /dev/null +++ b/libraries/src/test/resources/ABC.txt @@ -0,0 +1 @@ +Hello World from ABC.txt!!! \ No newline at end of file diff --git a/libraries/src/test/resources/aaa.txt b/libraries/src/test/resources/aaa.txt new file mode 100644 index 0000000000..e5875f97d6 --- /dev/null +++ b/libraries/src/test/resources/aaa.txt @@ -0,0 +1 @@ +Hello World from aaa.txt!!! \ No newline at end of file diff --git a/libraries/src/test/resources/fileTest.txt b/libraries/src/test/resources/fileTest.txt new file mode 100644 index 0000000000..ce4bea208b --- /dev/null +++ b/libraries/src/test/resources/fileTest.txt @@ -0,0 +1 @@ +Hello World from fileTest.txt!!! \ No newline at end of file diff --git a/libraries/src/test/resources/sample.txt b/libraries/src/test/resources/sample.txt new file mode 100644 index 0000000000..20f137b416 --- /dev/null +++ b/libraries/src/test/resources/sample.txt @@ -0,0 +1,2 @@ +line 1 +a second line \ No newline at end of file diff --git a/linkrest/README.md b/linkrest/README.md new file mode 100644 index 0000000000..33cf930b18 --- /dev/null +++ b/linkrest/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Guide to LinkRest](http://www.baeldung.com/linkrest) diff --git a/linkrest/WebContent/META-INF/MANIFEST.MF b/linkrest/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..254272e1c0 --- /dev/null +++ b/linkrest/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/linkrest/WebContent/WEB-INF/web.xml b/linkrest/WebContent/WEB-INF/web.xml new file mode 100644 index 0000000000..046c82b08a --- /dev/null +++ b/linkrest/WebContent/WEB-INF/web.xml @@ -0,0 +1,20 @@ + + + linkrest + + linkrest + org.glassfish.jersey.servlet.ServletContainer + + javax.ws.rs.Application + com.baeldung.LinkRestApplication + + 1 + + + linkrest + /* + + \ No newline at end of file diff --git a/linkrest/pom.xml b/linkrest/pom.xml new file mode 100644 index 0000000000..aa2f0f8bda --- /dev/null +++ b/linkrest/pom.xml @@ -0,0 +1,81 @@ + + 4.0.0 + com.baeldung + linkrest + 0.0.1-SNAPSHOT + war + + + + com.nhl.link.rest + link-rest + ${linkrest.version} + + + org.glassfish.jersey.containers + jersey-container-servlet + ${jersey.version} + + + org.glassfish.jersey.media + jersey-media-moxy + ${jersey.version} + + + com.h2database + h2 + ${h2.version} + + + + + + + maven-compiler-plugin + 3.5 + + 1.8 + 1.8 + + + + maven-war-plugin + 2.6 + + WebContent + false + + + + org.apache.cayenne.plugins + cayenne-maven-plugin + ${cayenne.version} + + + ${project.basedir}/src/main/resources/linkrest.map.xml + + + + + + cgen + + + + + + org.apache.cayenne.plugins + cayenne-modeler-maven-plugin + ${cayenne.version} + + + + + + 2.9 + 4.0.B1 + 1.4.196 + 2.25.1 + + \ No newline at end of file diff --git a/linkrest/src/main/java/com/baeldung/LinkRestApplication.java b/linkrest/src/main/java/com/baeldung/LinkRestApplication.java new file mode 100644 index 0000000000..7a2f7c8903 --- /dev/null +++ b/linkrest/src/main/java/com/baeldung/LinkRestApplication.java @@ -0,0 +1,24 @@ +package com.baeldung; + + +import javax.ws.rs.ApplicationPath; + +import org.apache.cayenne.configuration.server.ServerRuntime; +import org.glassfish.jersey.server.ResourceConfig; + +import com.nhl.link.rest.runtime.LinkRestBuilder; +import com.nhl.link.rest.runtime.LinkRestRuntime; + +@ApplicationPath("/linkrest") +public class LinkRestApplication extends ResourceConfig { + + public LinkRestApplication() { + ServerRuntime cayenneRuntime = ServerRuntime.builder() + .addConfig("cayenne-linkrest-project.xml") + .build(); + LinkRestRuntime lrRuntime = LinkRestBuilder.build(cayenneRuntime); + super.register(lrRuntime); + packages("com.baeldung.linkrest.apis"); + } + +} diff --git a/linkrest/src/main/java/com/baeldung/cayenne/Department.java b/linkrest/src/main/java/com/baeldung/cayenne/Department.java new file mode 100644 index 0000000000..ed7a2bd795 --- /dev/null +++ b/linkrest/src/main/java/com/baeldung/cayenne/Department.java @@ -0,0 +1,9 @@ +package com.baeldung.cayenne; + +import com.baeldung.cayenne.auto._Department; + +public class Department extends _Department { + + private static final long serialVersionUID = 1L; + +} diff --git a/linkrest/src/main/java/com/baeldung/cayenne/Employee.java b/linkrest/src/main/java/com/baeldung/cayenne/Employee.java new file mode 100644 index 0000000000..632ea4fbf9 --- /dev/null +++ b/linkrest/src/main/java/com/baeldung/cayenne/Employee.java @@ -0,0 +1,9 @@ +package com.baeldung.cayenne; + +import com.baeldung.cayenne.auto._Employee; + +public class Employee extends _Employee { + + private static final long serialVersionUID = 1L; + +} diff --git a/linkrest/src/main/java/com/baeldung/cayenne/auto/_Department.java b/linkrest/src/main/java/com/baeldung/cayenne/auto/_Department.java new file mode 100644 index 0000000000..4111a8c8b2 --- /dev/null +++ b/linkrest/src/main/java/com/baeldung/cayenne/auto/_Department.java @@ -0,0 +1,44 @@ +package com.baeldung.cayenne.auto; + +import java.util.List; + +import org.apache.cayenne.CayenneDataObject; +import org.apache.cayenne.exp.Property; + +import com.baeldung.cayenne.Employee; + +/** + * Class _Department was generated by Cayenne. + * It is probably a good idea to avoid changing this class manually, + * since it may be overwritten next time code is regenerated. + * If you need to make any customizations, please use subclass. + */ +public abstract class _Department extends CayenneDataObject { + + private static final long serialVersionUID = 1L; + + public static final String DEP_ID_PK_COLUMN = "dep_id"; + + public static final Property NAME = Property.create("name", String.class); + public static final Property> EMPLOYEES = Property.create("employees", List.class); + + public void setName(String name) { + writeProperty("name", name); + } + public String getName() { + return (String)readProperty("name"); + } + + public void addToEmployees(Employee obj) { + addToManyTarget("employees", obj, true); + } + public void removeFromEmployees(Employee obj) { + removeToManyTarget("employees", obj, true); + } + @SuppressWarnings("unchecked") + public List getEmployees() { + return (List)readProperty("employees"); + } + + +} diff --git a/linkrest/src/main/java/com/baeldung/cayenne/auto/_Employee.java b/linkrest/src/main/java/com/baeldung/cayenne/auto/_Employee.java new file mode 100644 index 0000000000..50e1880a56 --- /dev/null +++ b/linkrest/src/main/java/com/baeldung/cayenne/auto/_Employee.java @@ -0,0 +1,39 @@ +package com.baeldung.cayenne.auto; + +import org.apache.cayenne.CayenneDataObject; +import org.apache.cayenne.exp.Property; + +import com.baeldung.cayenne.Department; + +/** + * Class _Employee was generated by Cayenne. + * It is probably a good idea to avoid changing this class manually, + * since it may be overwritten next time code is regenerated. + * If you need to make any customizations, please use subclass. + */ +public abstract class _Employee extends CayenneDataObject { + + private static final long serialVersionUID = 1L; + + public static final String EMP_ID_PK_COLUMN = "emp_id"; + + public static final Property NAME = Property.create("name", String.class); + public static final Property DEPARTMENT = Property.create("department", Department.class); + + public void setName(String name) { + writeProperty("name", name); + } + public String getName() { + return (String)readProperty("name"); + } + + public void setDepartment(Department department) { + setToOneTarget("department", department, true); + } + + public Department getDepartment() { + return (Department)readProperty("department"); + } + + +} diff --git a/linkrest/src/main/java/com/baeldung/linkrest/apis/DepartmentResource.java b/linkrest/src/main/java/com/baeldung/linkrest/apis/DepartmentResource.java new file mode 100644 index 0000000000..f4090b580e --- /dev/null +++ b/linkrest/src/main/java/com/baeldung/linkrest/apis/DepartmentResource.java @@ -0,0 +1,58 @@ +package com.baeldung.linkrest.apis; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Configuration; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; + +import com.baeldung.cayenne.Department; +import com.nhl.link.rest.DataResponse; +import com.nhl.link.rest.LinkRest; +import com.nhl.link.rest.SimpleResponse; + +@Path("department") +@Produces(MediaType.APPLICATION_JSON) +public class DepartmentResource { + + @Context + private Configuration config; + + @GET + public DataResponse getAll(@Context UriInfo uriInfo) { + return LinkRest.select(Department.class, config).uri(uriInfo).get(); + } + + @GET + @Path("{id}") + public DataResponse getOne(@PathParam("id") int id, @Context UriInfo uriInfo) { + return LinkRest.select(Department.class, config).byId(id).uri(uriInfo).getOne(); + } + + @POST + public SimpleResponse create(String data) { + return LinkRest.create(Department.class, config).sync(data); + } + + @PUT + public SimpleResponse createOrUpdate(String data) { + return LinkRest.createOrUpdate(Department.class, config).sync(data); + } + + @Path("{id}/employees") + public EmployeeSubResource getEmployees(@PathParam("id") int id, @Context UriInfo uriInfo) { + return new EmployeeSubResource(id, config); + } + + @DELETE + @Path("{id}") + public SimpleResponse delete(@PathParam("id") int id) { + return LinkRest.delete(Department.class, config).id(id).delete(); + } +} diff --git a/linkrest/src/main/java/com/baeldung/linkrest/apis/EmployeeSubResource.java b/linkrest/src/main/java/com/baeldung/linkrest/apis/EmployeeSubResource.java new file mode 100644 index 0000000000..ba9c3759bb --- /dev/null +++ b/linkrest/src/main/java/com/baeldung/linkrest/apis/EmployeeSubResource.java @@ -0,0 +1,65 @@ +package com.baeldung.linkrest.apis; + +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Configuration; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; + +import com.baeldung.cayenne.Department; +import com.baeldung.cayenne.Employee; +import com.nhl.link.rest.DataResponse; +import com.nhl.link.rest.LinkRest; +import com.nhl.link.rest.SimpleResponse; + +@Produces(MediaType.APPLICATION_JSON) +public class EmployeeSubResource { + + private Configuration config; + + private int departmentId; + + public EmployeeSubResource(int departmentId, Configuration config) { + this.departmentId = departmentId; + this.config = config; + } + + public EmployeeSubResource() { + } + + @GET + public DataResponse getAll(@Context UriInfo uriInfo) { + return LinkRest.select(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).uri(uriInfo).get(); + } + + @GET + @Path("{id}") + public DataResponse getOne(@PathParam("id") int id, @Context UriInfo uriInfo) { + return LinkRest.select(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).byId(id).uri(uriInfo).getOne(); + } + + @POST + public SimpleResponse create(String data) { + + return LinkRest.create(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).sync(data); + } + + @PUT + public SimpleResponse createOrUpdate(String data) { + return LinkRest.create(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).sync(data); + } + + @DELETE + @Path("{id}") + public SimpleResponse delete(@PathParam("id") int id) { + return LinkRest.delete(Employee.class, config).toManyParent(Department.class, departmentId, Department.EMPLOYEES).id(id).delete(); + + } + +} diff --git a/linkrest/src/main/resources/cayenne-linkrest-project.xml b/linkrest/src/main/resources/cayenne-linkrest-project.xml new file mode 100644 index 0000000000..8a4ba39c4d --- /dev/null +++ b/linkrest/src/main/resources/cayenne-linkrest-project.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/linkrest/src/main/resources/linkrest.map.xml b/linkrest/src/main/resources/linkrest.map.xml new file mode 100644 index 0000000000..105d7d9d14 --- /dev/null +++ b/linkrest/src/main/resources/linkrest.map.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/logging-modules/README.md b/logging-modules/README.md new file mode 100644 index 0000000000..23458cf30b --- /dev/null +++ b/logging-modules/README.md @@ -0,0 +1,3 @@ + +## Logging Modules + diff --git a/log-mdc/README.md b/logging-modules/log-mdc/README.md similarity index 100% rename from log-mdc/README.md rename to logging-modules/log-mdc/README.md diff --git a/log-mdc/pom.xml b/logging-modules/log-mdc/pom.xml similarity index 98% rename from log-mdc/pom.xml rename to logging-modules/log-mdc/pom.xml index e91d4e231e..5551585372 100644 --- a/log-mdc/pom.xml +++ b/logging-modules/log-mdc/pom.xml @@ -12,6 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/log-mdc/src/main/java/com/baeldung/config/AppConfiguration.java b/logging-modules/log-mdc/src/main/java/com/baeldung/config/AppConfiguration.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/config/AppConfiguration.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/config/AppConfiguration.java diff --git a/log-mdc/src/main/java/com/baeldung/config/AppInitializer.java b/logging-modules/log-mdc/src/main/java/com/baeldung/config/AppInitializer.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/config/AppInitializer.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/config/AppInitializer.java diff --git a/log-mdc/src/main/java/com/baeldung/mdc/TransactionFactory.java b/logging-modules/log-mdc/src/main/java/com/baeldung/mdc/TransactionFactory.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/mdc/TransactionFactory.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/mdc/TransactionFactory.java diff --git a/log-mdc/src/main/java/com/baeldung/mdc/Transfer.java b/logging-modules/log-mdc/src/main/java/com/baeldung/mdc/Transfer.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/mdc/Transfer.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/mdc/Transfer.java diff --git a/log-mdc/src/main/java/com/baeldung/mdc/TransferDemo.java b/logging-modules/log-mdc/src/main/java/com/baeldung/mdc/TransferDemo.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/mdc/TransferDemo.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/mdc/TransferDemo.java diff --git a/log-mdc/src/main/java/com/baeldung/mdc/TransferService.java b/logging-modules/log-mdc/src/main/java/com/baeldung/mdc/TransferService.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/mdc/TransferService.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/mdc/TransferService.java diff --git a/log-mdc/src/main/java/com/baeldung/mdc/log4j/Log4JRunnable.java b/logging-modules/log-mdc/src/main/java/com/baeldung/mdc/log4j/Log4JRunnable.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/mdc/log4j/Log4JRunnable.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/mdc/log4j/Log4JRunnable.java diff --git a/log-mdc/src/main/java/com/baeldung/mdc/log4j/Log4JTransferService.java b/logging-modules/log-mdc/src/main/java/com/baeldung/mdc/log4j/Log4JTransferService.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/mdc/log4j/Log4JTransferService.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/mdc/log4j/Log4JTransferService.java diff --git a/log-mdc/src/main/java/com/baeldung/mdc/log4j2/Log4J2Runnable.java b/logging-modules/log-mdc/src/main/java/com/baeldung/mdc/log4j2/Log4J2Runnable.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/mdc/log4j2/Log4J2Runnable.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/mdc/log4j2/Log4J2Runnable.java diff --git a/log-mdc/src/main/java/com/baeldung/mdc/log4j2/Log4J2TransferService.java b/logging-modules/log-mdc/src/main/java/com/baeldung/mdc/log4j2/Log4J2TransferService.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/mdc/log4j2/Log4J2TransferService.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/mdc/log4j2/Log4J2TransferService.java diff --git a/log-mdc/src/main/java/com/baeldung/mdc/slf4j/Slf4TransferService.java b/logging-modules/log-mdc/src/main/java/com/baeldung/mdc/slf4j/Slf4TransferService.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/mdc/slf4j/Slf4TransferService.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/mdc/slf4j/Slf4TransferService.java diff --git a/log-mdc/src/main/java/com/baeldung/mdc/slf4j/Slf4jRunnable.java b/logging-modules/log-mdc/src/main/java/com/baeldung/mdc/slf4j/Slf4jRunnable.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/mdc/slf4j/Slf4jRunnable.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/mdc/slf4j/Slf4jRunnable.java diff --git a/log-mdc/src/main/java/com/baeldung/ndc/Investment.java b/logging-modules/log-mdc/src/main/java/com/baeldung/ndc/Investment.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/ndc/Investment.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/ndc/Investment.java diff --git a/log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java b/logging-modules/log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/ndc/controller/JBossLoggingController.java diff --git a/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4J2Controller.java b/logging-modules/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4J2Controller.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/ndc/controller/Log4J2Controller.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4J2Controller.java diff --git a/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4JController.java b/logging-modules/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4JController.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/ndc/controller/Log4JController.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/ndc/controller/Log4JController.java diff --git a/log-mdc/src/main/java/com/baeldung/ndc/service/InvestmentService.java b/logging-modules/log-mdc/src/main/java/com/baeldung/ndc/service/InvestmentService.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/ndc/service/InvestmentService.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/ndc/service/InvestmentService.java diff --git a/log-mdc/src/main/java/com/baeldung/ndc/service/JBossLoggingInvestmentService.java b/logging-modules/log-mdc/src/main/java/com/baeldung/ndc/service/JBossLoggingInvestmentService.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/ndc/service/JBossLoggingInvestmentService.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/ndc/service/JBossLoggingInvestmentService.java diff --git a/log-mdc/src/main/java/com/baeldung/ndc/service/Log4J2InvestmentService.java b/logging-modules/log-mdc/src/main/java/com/baeldung/ndc/service/Log4J2InvestmentService.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/ndc/service/Log4J2InvestmentService.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/ndc/service/Log4J2InvestmentService.java diff --git a/log-mdc/src/main/java/com/baeldung/ndc/service/Log4JInvestmentService.java b/logging-modules/log-mdc/src/main/java/com/baeldung/ndc/service/Log4JInvestmentService.java similarity index 100% rename from log-mdc/src/main/java/com/baeldung/ndc/service/Log4JInvestmentService.java rename to logging-modules/log-mdc/src/main/java/com/baeldung/ndc/service/Log4JInvestmentService.java diff --git a/log-mdc/src/main/resources/log4j.properties b/logging-modules/log-mdc/src/main/resources/log4j.properties similarity index 100% rename from log-mdc/src/main/resources/log4j.properties rename to logging-modules/log-mdc/src/main/resources/log4j.properties diff --git a/log-mdc/src/main/resources/log4j2.xml b/logging-modules/log-mdc/src/main/resources/log4j2.xml similarity index 100% rename from log-mdc/src/main/resources/log4j2.xml rename to logging-modules/log-mdc/src/main/resources/log4j2.xml diff --git a/log-mdc/src/main/resources/logback.xml b/logging-modules/log-mdc/src/main/resources/logback.xml similarity index 100% rename from log-mdc/src/main/resources/logback.xml rename to logging-modules/log-mdc/src/main/resources/logback.xml diff --git a/log-mdc/src/test/java/com/baeldung/mdc/log4j/DemoIntegrationTest.java b/logging-modules/log-mdc/src/test/java/com/baeldung/mdc/log4j/DemoIntegrationTest.java similarity index 100% rename from log-mdc/src/test/java/com/baeldung/mdc/log4j/DemoIntegrationTest.java rename to logging-modules/log-mdc/src/test/java/com/baeldung/mdc/log4j/DemoIntegrationTest.java diff --git a/log-mdc/src/test/java/com/baeldung/mdc/log4j2/DemoIntegrationTest.java b/logging-modules/log-mdc/src/test/java/com/baeldung/mdc/log4j2/DemoIntegrationTest.java similarity index 100% rename from log-mdc/src/test/java/com/baeldung/mdc/log4j2/DemoIntegrationTest.java rename to logging-modules/log-mdc/src/test/java/com/baeldung/mdc/log4j2/DemoIntegrationTest.java diff --git a/log-mdc/src/test/java/com/baeldung/mdc/slf4j/DemoIntegrationTest.java b/logging-modules/log-mdc/src/test/java/com/baeldung/mdc/slf4j/DemoIntegrationTest.java similarity index 100% rename from log-mdc/src/test/java/com/baeldung/mdc/slf4j/DemoIntegrationTest.java rename to logging-modules/log-mdc/src/test/java/com/baeldung/mdc/slf4j/DemoIntegrationTest.java diff --git a/log-mdc/src/test/java/com/baeldung/ndc/NDCLogIntegrationTest.java b/logging-modules/log-mdc/src/test/java/com/baeldung/ndc/NDCLogIntegrationTest.java similarity index 100% rename from log-mdc/src/test/java/com/baeldung/ndc/NDCLogIntegrationTest.java rename to logging-modules/log-mdc/src/test/java/com/baeldung/ndc/NDCLogIntegrationTest.java diff --git a/log4j/README.md b/logging-modules/log4j/README.md similarity index 83% rename from log4j/README.md rename to logging-modules/log4j/README.md index 3c0258142c..8aae1b5826 100644 --- a/log4j/README.md +++ b/logging-modules/log4j/README.md @@ -2,6 +2,5 @@ - [Introduction to Java Logging](http://www.baeldung.com/java-logging-intro) - [Introduction to SLF4J](http://www.baeldung.com/slf4j-with-log4j2-logback) - [Generate equals() and hashCode() with Eclipse](http://www.baeldung.com/java-eclipse-equals-and-hashcode) -- [A Guide To Java Regular Expressions API](http://www.baeldung.com/regular-expressions-java) - [Introduction to SLF4J](http://www.baeldung.com/slf4j-with-log4j2-logback) - [A Guide to Rolling File Appenders](http://www.baeldung.com/java-logging-rolling-file-appenders) diff --git a/log4j/pom.xml b/logging-modules/log4j/pom.xml similarity index 90% rename from log4j/pom.xml rename to logging-modules/log4j/pom.xml index 2e73baac49..6a3fbde393 100644 --- a/log4j/pom.xml +++ b/logging-modules/log4j/pom.xml @@ -11,6 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ @@ -26,12 +27,6 @@ ${log4j.version} - - log4j - apache-log4j-extras - ${log4j.version} - - org.apache.logging.log4j diff --git a/log4j/src/main/java/com/baeldung/log4j/Log4jExample.java b/logging-modules/log4j/src/main/java/com/baeldung/log4j/Log4jExample.java similarity index 100% rename from log4j/src/main/java/com/baeldung/log4j/Log4jExample.java rename to logging-modules/log4j/src/main/java/com/baeldung/log4j/Log4jExample.java diff --git a/log4j/src/main/java/com/baeldung/log4j/Log4jRollingExample.java b/logging-modules/log4j/src/main/java/com/baeldung/log4j/Log4jRollingExample.java similarity index 100% rename from log4j/src/main/java/com/baeldung/log4j/Log4jRollingExample.java rename to logging-modules/log4j/src/main/java/com/baeldung/log4j/Log4jRollingExample.java diff --git a/log4j/src/main/java/com/baeldung/log4j2/Log4j2Example.java b/logging-modules/log4j/src/main/java/com/baeldung/log4j2/Log4j2Example.java similarity index 100% rename from log4j/src/main/java/com/baeldung/log4j2/Log4j2Example.java rename to logging-modules/log4j/src/main/java/com/baeldung/log4j2/Log4j2Example.java diff --git a/log4j/src/main/java/com/baeldung/log4j2/Log4j2RollingExample.java b/logging-modules/log4j/src/main/java/com/baeldung/log4j2/Log4j2RollingExample.java similarity index 100% rename from log4j/src/main/java/com/baeldung/log4j2/Log4j2RollingExample.java rename to logging-modules/log4j/src/main/java/com/baeldung/log4j2/Log4j2RollingExample.java diff --git a/log4j/src/main/java/com/baeldung/logback/LogbackExample.java b/logging-modules/log4j/src/main/java/com/baeldung/logback/LogbackExample.java similarity index 100% rename from log4j/src/main/java/com/baeldung/logback/LogbackExample.java rename to logging-modules/log4j/src/main/java/com/baeldung/logback/LogbackExample.java diff --git a/log4j/src/main/java/com/baeldung/logback/LogbackRollingExample.java b/logging-modules/log4j/src/main/java/com/baeldung/logback/LogbackRollingExample.java similarity index 100% rename from log4j/src/main/java/com/baeldung/logback/LogbackRollingExample.java rename to logging-modules/log4j/src/main/java/com/baeldung/logback/LogbackRollingExample.java diff --git a/log4j/src/main/java/com/baeldung/slf4j/Slf4jExample.java b/logging-modules/log4j/src/main/java/com/baeldung/slf4j/Slf4jExample.java similarity index 100% rename from log4j/src/main/java/com/baeldung/slf4j/Slf4jExample.java rename to logging-modules/log4j/src/main/java/com/baeldung/slf4j/Slf4jExample.java diff --git a/log4j/src/main/java/com/baeldung/slf4j/Slf4jRollingExample.java b/logging-modules/log4j/src/main/java/com/baeldung/slf4j/Slf4jRollingExample.java similarity index 100% rename from log4j/src/main/java/com/baeldung/slf4j/Slf4jRollingExample.java rename to logging-modules/log4j/src/main/java/com/baeldung/slf4j/Slf4jRollingExample.java diff --git a/log4j/src/main/resources/log4j.xml b/logging-modules/log4j/src/main/resources/log4j.xml similarity index 100% rename from log4j/src/main/resources/log4j.xml rename to logging-modules/log4j/src/main/resources/log4j.xml diff --git a/log4j/src/main/resources/log4j2.xml b/logging-modules/log4j/src/main/resources/log4j2.xml similarity index 100% rename from log4j/src/main/resources/log4j2.xml rename to logging-modules/log4j/src/main/resources/log4j2.xml diff --git a/log4j/src/main/resources/logback.xml b/logging-modules/log4j/src/main/resources/logback.xml similarity index 100% rename from log4j/src/main/resources/logback.xml rename to logging-modules/log4j/src/main/resources/logback.xml diff --git a/log4j2/README.md b/logging-modules/log4j2/README.md similarity index 62% rename from log4j2/README.md rename to logging-modules/log4j2/README.md index 3afd842c82..57ca4df21b 100644 --- a/log4j2/README.md +++ b/logging-modules/log4j2/README.md @@ -1,3 +1,4 @@ ### Relevant articles - [Intro to Log4j2 – Appenders, Layouts and Filters](http://www.baeldung.com/log4j2-appenders-layouts-filters) +- [Log4j 2 and Lambda Expressions](http://www.baeldung.com/log4j-2-lazy-logging) diff --git a/log4j2/pom.xml b/logging-modules/log4j2/pom.xml similarity index 98% rename from log4j2/pom.xml rename to logging-modules/log4j2/pom.xml index ea398af845..48608fbc80 100644 --- a/log4j2/pom.xml +++ b/logging-modules/log4j2/pom.xml @@ -9,7 +9,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - .. + ../../ diff --git a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingIntegrationTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingIntegrationTest.java similarity index 100% rename from log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingIntegrationTest.java rename to logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/CustomLoggingIntegrationTest.java diff --git a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/LambdaExpressionsIntegrationTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/LambdaExpressionsIntegrationTest.java similarity index 100% rename from log4j2/src/test/java/com/baeldung/logging/log4j2/tests/LambdaExpressionsIntegrationTest.java rename to logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/LambdaExpressionsIntegrationTest.java diff --git a/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/jdbc/ConnectionFactory.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/jdbc/ConnectionFactory.java similarity index 100% rename from log4j2/src/test/java/com/baeldung/logging/log4j2/tests/jdbc/ConnectionFactory.java rename to logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/jdbc/ConnectionFactory.java diff --git a/log4j2/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml b/logging-modules/log4j2/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml similarity index 100% rename from log4j2/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml rename to logging-modules/log4j2/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml diff --git a/log4j2/src/test/resources/log4j2.xml b/logging-modules/log4j2/src/test/resources/log4j2.xml similarity index 100% rename from log4j2/src/test/resources/log4j2.xml rename to logging-modules/log4j2/src/test/resources/log4j2.xml diff --git a/.metadata/.lock b/logging-modules/logback/README.md similarity index 100% rename from .metadata/.lock rename to logging-modules/logback/README.md diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml new file mode 100644 index 0000000000..8169134442 --- /dev/null +++ b/logging-modules/logback/pom.xml @@ -0,0 +1,35 @@ + + + + 4.0.0 + + logback + logback + 0.1-SNAPSHOT + + + UTF-8 + 1.2.3 + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + + diff --git a/logging-modules/logback/src/main/java/com/baeldung/logback/Example.java b/logging-modules/logback/src/main/java/com/baeldung/logback/Example.java new file mode 100644 index 0000000000..e3d09dc321 --- /dev/null +++ b/logging-modules/logback/src/main/java/com/baeldung/logback/Example.java @@ -0,0 +1,14 @@ +package com.baeldung.logback; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Example { + + private static final Logger logger = LoggerFactory.getLogger(Example.class); + + public static void main(String[] args) { + logger.info("Example log from {}", Example.class.getSimpleName()); + } + +} diff --git a/logging-modules/logback/src/main/java/com/baeldung/logback/MapAppender.java b/logging-modules/logback/src/main/java/com/baeldung/logback/MapAppender.java new file mode 100644 index 0000000000..99cc6488e5 --- /dev/null +++ b/logging-modules/logback/src/main/java/com/baeldung/logback/MapAppender.java @@ -0,0 +1,37 @@ +package com.baeldung.logback; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; + +import java.util.HashMap; +import java.util.Map; + +public class MapAppender extends AppenderBase { + + private final Map eventMap = new HashMap<>(); + + private String prefix; + + @Override + protected void append(final ILoggingEvent event) { + if (prefix == null || "".equals(prefix)) { + addError("Prefix is not set for MapAppender."); + return; + } + + eventMap.put(prefix + System.currentTimeMillis(), event); + } + + public String getPrefix() { + return prefix; + } + + public void setPrefix(final String prefix) { + this.prefix = prefix; + } + + public Map getEventMap() { + return eventMap; + } + +} diff --git a/logging-modules/logback/src/main/resources/logback.xml b/logging-modules/logback/src/main/resources/logback.xml new file mode 100644 index 0000000000..37ae2adbb0 --- /dev/null +++ b/logging-modules/logback/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + test + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + \ No newline at end of file diff --git a/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderIntegrationTest.java b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderIntegrationTest.java new file mode 100644 index 0000000000..20366a229d --- /dev/null +++ b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderIntegrationTest.java @@ -0,0 +1,33 @@ +package com.baeldung.logback; + +import ch.qos.logback.classic.Logger; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.assertEquals; + +public class MapAppenderIntegrationTest { + + private Logger rootLogger; + + @Before + public void setUp() throws Exception { + rootLogger = (Logger) LoggerFactory.getLogger("ROOT"); + } + + @Test + public void whenLoggerEmitsLoggingEvent_thenAppenderReceivesEvent() throws Exception { + rootLogger.info("Test from {}", this.getClass().getSimpleName()); + MapAppender appender = (MapAppender) rootLogger.getAppender("map"); + assertEquals(appender.getEventMap().size(), 1); + } + + @Test + public void givenNoPrefixSet_whenLoggerEmitsEvent_thenAppenderReceivesNoEvent() throws Exception { + rootLogger.info("Test from {}", this.getClass().getSimpleName()); + MapAppender appender = (MapAppender) rootLogger.getAppender("badMap"); + assertEquals(appender.getEventMap().size(), 0); + } + +} diff --git a/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderTest.java b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderTest.java new file mode 100644 index 0000000000..a5a938a923 --- /dev/null +++ b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderTest.java @@ -0,0 +1,60 @@ +package com.baeldung.logback; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.BasicStatusManager; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class MapAppenderTest { + + private LoggerContext ctx; + + private MapAppender mapAppender = new MapAppender(); + + private LoggingEvent event; + + @Before + public void setUp() throws Exception { + ctx = new LoggerContext(); + ctx.setName("test context"); + ctx.setStatusManager(new BasicStatusManager()); + mapAppender.setContext(ctx); + mapAppender.setPrefix("prefix"); + event = new LoggingEvent("fqcn", ctx.getLogger("logger"), Level.INFO, "Test message for logback appender", null, new Object[0]); + ctx.start(); + } + + @After + public void tearDown() throws Exception { + ctx.stop(); + mapAppender.stop(); + } + + @Test + public void whenPrefixIsNull_thenMapAppenderDoesNotLog() throws Exception { + mapAppender.setPrefix(null); + mapAppender.append(event); + assertTrue(mapAppender.getEventMap().isEmpty()); + } + + @Test + public void whenPrefixIsEmpty_thenMapAppenderDoesNotLog() throws Exception { + mapAppender.setPrefix(""); + mapAppender.append(event); + assertTrue(mapAppender.getEventMap().isEmpty()); + } + + @Test + public void whenLogMessageIsEmitted_thenMapAppenderReceivesMessage() throws Exception { + mapAppender.append(event); + assertEquals(mapAppender.getEventMap().size(), 1); + mapAppender.getEventMap().forEach((k, v) -> assertTrue(k.startsWith("prefix"))); + } + +} diff --git a/logging-modules/logback/src/test/resources/logback-test.xml b/logging-modules/logback/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8254e6ac80 --- /dev/null +++ b/logging-modules/logback/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + test + + + + + + + + + + \ No newline at end of file diff --git a/lucene/pom.xml b/lucene/pom.xml new file mode 100644 index 0000000000..6659d9ac32 --- /dev/null +++ b/lucene/pom.xml @@ -0,0 +1,35 @@ + + 4.0.0 + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + lucene + 0.0.1-SNAPSHOT + lucene + An Apache Lucene demo application + + + + + org.apache.lucene + lucene-core + 7.1.0 + + + + org.apache.lucene + lucene-queryparser + 7.1.0 + + + + junit + junit + 4.12 + test + + + \ No newline at end of file diff --git a/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java b/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java new file mode 100644 index 0000000000..97b1ec7b5d --- /dev/null +++ b/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java @@ -0,0 +1,128 @@ +package com.baeldung.lucene; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.SortedDocValuesField; +import org.apache.lucene.document.TextField; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.Term; +import org.apache.lucene.queryparser.classic.ParseException; +import org.apache.lucene.queryparser.classic.QueryParser; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.Directory; +import org.apache.lucene.util.BytesRef; + +public class InMemoryLuceneIndex { + + private Directory memoryIndex; + private StandardAnalyzer analyzer; + + public InMemoryLuceneIndex(Directory memoryIndex, StandardAnalyzer analyzer) { + super(); + this.memoryIndex = memoryIndex; + this.analyzer = analyzer; + } + + /** + * + * @param title + * @param body + */ + public void indexDocument(String title, String body) { + + IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer); + try { + IndexWriter writter = new IndexWriter(memoryIndex, indexWriterConfig); + Document document = new Document(); + + document.add(new TextField("title", title, Field.Store.YES)); + document.add(new TextField("body", body, Field.Store.YES)); + document.add(new SortedDocValuesField("title", new BytesRef(title))); + + writter.addDocument(document); + writter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public List searchIndex(String inField, String queryString) { + try { + Query query = new QueryParser(inField, analyzer).parse(queryString); + + IndexReader indexReader = DirectoryReader.open(memoryIndex); + IndexSearcher searcher = new IndexSearcher(indexReader); + TopDocs topDocs = searcher.search(query, 10); + List documents = new ArrayList<>(); + for (ScoreDoc scoreDoc : topDocs.scoreDocs) { + documents.add(searcher.doc(scoreDoc.doc)); + } + + return documents; + } catch (IOException | ParseException e) { + e.printStackTrace(); + } + return null; + + } + + public void deleteDocument(Term term) { + try { + IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer); + IndexWriter writter = new IndexWriter(memoryIndex, indexWriterConfig); + writter.deleteDocuments(term); + writter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public List searchIndex(Query query) { + try { + IndexReader indexReader = DirectoryReader.open(memoryIndex); + IndexSearcher searcher = new IndexSearcher(indexReader); + TopDocs topDocs = searcher.search(query, 10); + List documents = new ArrayList<>(); + for (ScoreDoc scoreDoc : topDocs.scoreDocs) { + documents.add(searcher.doc(scoreDoc.doc)); + } + + return documents; + } catch (IOException e) { + e.printStackTrace(); + } + return null; + + } + + public List searchIndex(Query query, Sort sort) { + try { + IndexReader indexReader = DirectoryReader.open(memoryIndex); + IndexSearcher searcher = new IndexSearcher(indexReader); + TopDocs topDocs = searcher.search(query, 10, sort); + List documents = new ArrayList<>(); + for (ScoreDoc scoreDoc : topDocs.scoreDocs) { + documents.add(searcher.doc(scoreDoc.doc)); + } + + return documents; + } catch (IOException e) { + e.printStackTrace(); + } + return null; + + } + +} diff --git a/lucene/src/test/java/com/baeldung/lucene/LuceneInMemorySearchTest.java b/lucene/src/test/java/com/baeldung/lucene/LuceneInMemorySearchTest.java new file mode 100644 index 0000000000..acf688cb99 --- /dev/null +++ b/lucene/src/test/java/com/baeldung/lucene/LuceneInMemorySearchTest.java @@ -0,0 +1,152 @@ +package com.baeldung.lucene; + +import java.util.List; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.FuzzyQuery; +import org.apache.lucene.search.PhraseQuery; +import org.apache.lucene.search.PrefixQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.SortField; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.WildcardQuery; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.BytesRef; +import org.junit.Assert; +import org.junit.Test; + +public class LuceneInMemorySearchTest { + + @Test + public void givenSearchQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("Hello world", "Some hello world "); + + List documents = inMemoryLuceneIndex.searchIndex("body", "world"); + + Assert.assertEquals("Hello world", documents.get(0).get("title")); + } + + @Test + public void givenTermQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("activity", "running in track"); + inMemoryLuceneIndex.indexDocument("activity", "Cars are running on road"); + + Term term = new Term("body", "running"); + Query query = new TermQuery(term); + + List documents = inMemoryLuceneIndex.searchIndex(query); + Assert.assertEquals(2, documents.size()); + } + + @Test + public void givenPrefixQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("article", "Lucene introduction"); + inMemoryLuceneIndex.indexDocument("article", "Introduction to Lucene"); + + Term term = new Term("body", "intro"); + Query query = new PrefixQuery(term); + + List documents = inMemoryLuceneIndex.searchIndex(query); + Assert.assertEquals(2, documents.size()); + } + + @Test + public void givenBooleanQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("Destination", "Las Vegas singapore car"); + inMemoryLuceneIndex.indexDocument("Commutes in singapore", "Bus Car Bikes"); + + Term term1 = new Term("body", "singapore"); + Term term2 = new Term("body", "car"); + + TermQuery query1 = new TermQuery(term1); + TermQuery query2 = new TermQuery(term2); + + BooleanQuery booleanQuery = new BooleanQuery.Builder().add(query1, BooleanClause.Occur.MUST) + .add(query2, BooleanClause.Occur.MUST).build(); + + List documents = inMemoryLuceneIndex.searchIndex(booleanQuery); + Assert.assertEquals(1, documents.size()); + } + + @Test + public void givenPhraseQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("quotes", "A rose by any other name would smell as sweet."); + + Query query = new PhraseQuery(1, "body", new BytesRef("smell"), new BytesRef("sweet")); + List documents = inMemoryLuceneIndex.searchIndex(query); + + Assert.assertEquals(1, documents.size()); + } + + @Test + public void givenFuzzyQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("article", "Halloween Festival"); + inMemoryLuceneIndex.indexDocument("decoration", "Decorations for Halloween"); + + Term term = new Term("body", "hallowen"); + Query query = new FuzzyQuery(term); + + List documents = inMemoryLuceneIndex.searchIndex(query); + Assert.assertEquals(2, documents.size()); + } + + @Test + public void givenWildCardQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("article", "Lucene introduction"); + inMemoryLuceneIndex.indexDocument("article", "Introducing Lucene with Spring"); + + Term term = new Term("body", "intro*"); + Query query = new WildcardQuery(term); + + List documents = inMemoryLuceneIndex.searchIndex(query); + Assert.assertEquals(2, documents.size()); + } + + @Test + public void givenSortFieldWhenSortedThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("Ganges", "River in India"); + inMemoryLuceneIndex.indexDocument("Mekong", "This river flows in south Asia"); + inMemoryLuceneIndex.indexDocument("Amazon", "Rain forest river"); + inMemoryLuceneIndex.indexDocument("Rhine", "Belongs to Europe"); + inMemoryLuceneIndex.indexDocument("Nile", "Longest River"); + + Term term = new Term("body", "river"); + Query query = new WildcardQuery(term); + + SortField sortField = new SortField("title", SortField.Type.STRING_VAL, false); + Sort sortByTitle = new Sort(sortField); + + List documents = inMemoryLuceneIndex.searchIndex(query, sortByTitle); + Assert.assertEquals(4, documents.size()); + Assert.assertEquals("Amazon", documents.get(0).getField("title").stringValue()); + } + + @Test + public void whenDocumentDeletedThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("Ganges", "River in India"); + inMemoryLuceneIndex.indexDocument("Mekong", "This river flows in south Asia"); + + Term term = new Term("title", "ganges"); + inMemoryLuceneIndex.deleteDocument(term); + + Query query = new TermQuery(term); + + List documents = inMemoryLuceneIndex.searchIndex(query); + Assert.assertEquals(0, documents.size()); + } + +} \ No newline at end of file diff --git a/mapstruct/pom.xml b/mapstruct/pom.xml index 17cf882d2b..ba67ccc2df 100644 --- a/mapstruct/pom.xml +++ b/mapstruct/pom.xml @@ -5,7 +5,6 @@ 4.0.0 mapstruct mapstruct - com.baeldung 1.0 jar diff --git a/metrics/README.md b/metrics/README.md index 09fe925604..c7772bffa0 100644 --- a/metrics/README.md +++ b/metrics/README.md @@ -2,3 +2,4 @@ - [Intro to Dropwizard Metrics](http://www.baeldung.com/dropwizard-metrics) - [Introduction to Netflix Servo](http://www.baeldung.com/netflix-servo) +- [Quick Guide to Micrometer](http://www.baeldung.com/micrometer) diff --git a/metrics/pom.xml b/metrics/pom.xml index 574c1ac132..25ce452d7a 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -16,6 +16,8 @@ 3.1.2 3.1.0 0.12.17 + 0.12.0.RELEASE + 2.0.0.M5 @@ -57,12 +59,64 @@ ${netflix.servo.ver} test + + + io.micrometer + micrometer-registry-atlas + ${micrometer.ver} + + + + io.micrometer + micrometer-spring-legacy + ${micrometer.ver} + + + + org.springframework.boot + spring-boot-starter-web + ${spring.boot.ver} + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.1 + com.fasterxml.jackson.dataformat jackson-dataformat-smile - 2.8.9 - test + 2.9.1 + + + + com.netflix.spectator + spectator-api + 0.57.1 + + + + org.springframework.boot + spring-boot-dependencies + pom + import + ${spring.boot.ver} + + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/libs-milestone + + false + + + + diff --git a/metrics/src/main/java/com/baeldung/metrics/micrometer/MicrometerApp.java b/metrics/src/main/java/com/baeldung/metrics/micrometer/MicrometerApp.java new file mode 100644 index 0000000000..cf818f6600 --- /dev/null +++ b/metrics/src/main/java/com/baeldung/metrics/micrometer/MicrometerApp.java @@ -0,0 +1,20 @@ +package com.baeldung.metrics.micrometer; + +import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class MicrometerApp { + + @Bean + JvmThreadMetrics threadMetrics() { + return new JvmThreadMetrics(); + } + + public static void main(String[] args) throws Exception { + SpringApplication.run(MicrometerApp.class, args); + } + +} diff --git a/metrics/src/main/java/com/baeldung/metrics/micrometer/PeopleController.java b/metrics/src/main/java/com/baeldung/metrics/micrometer/PeopleController.java new file mode 100644 index 0000000000..789e975a7f --- /dev/null +++ b/metrics/src/main/java/com/baeldung/metrics/micrometer/PeopleController.java @@ -0,0 +1,54 @@ +package com.baeldung.metrics.micrometer; + +import io.micrometer.core.annotation.Timed; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @author aiet + */ +@RestController +@Timed("people") +public class PeopleController { + + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); + + @GetMapping("/people") + @Timed(value = "people.all", longTask = true) + public List listPeople() throws InterruptedException { + int seconds2Sleep = SECURE_RANDOM.nextInt(500); + System.out.println(seconds2Sleep); + TimeUnit.MILLISECONDS.sleep(seconds2Sleep); + return Arrays.asList("Jim", "Tom", "Tim"); + } + + @PostMapping("/people") + @Timed(value = "people.update", longTask = true) + public List putPeople() throws InterruptedException { + int seconds2Sleep = SECURE_RANDOM.nextInt(1000); + System.out.println(seconds2Sleep); + TimeUnit.MILLISECONDS.sleep(seconds2Sleep); + return Arrays.asList("Jim", "Tom", "Tim"); + } + + @GetMapping("/asset") + @Timed(value = "people.asset", longTask = true) + public void test() throws Exception { + throw new Exception("error!"); + } + + @GetMapping("/property") + @Timed(value = "people.property", longTask = true) + public void property(HttpServletResponse response) throws IOException { + response.sendRedirect("/asset"); + } + +} diff --git a/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasTest.java b/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasTest.java new file mode 100644 index 0000000000..826e06d598 --- /dev/null +++ b/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasTest.java @@ -0,0 +1,275 @@ +package com.baeldung.metrics.micrometer; + +import com.netflix.spectator.atlas.AtlasConfig; +import io.micrometer.atlas.AtlasMeterRegistry; +import io.micrometer.core.instrument.*; +import io.micrometer.core.instrument.Timer; +import io.micrometer.core.instrument.composite.CompositeMeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import io.micrometer.core.instrument.stats.hist.Histogram; +import io.micrometer.core.instrument.stats.quantile.WindowSketchQuantiles; +import org.junit.Before; +import org.junit.Test; + +import java.time.Duration; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static io.micrometer.core.instrument.Meter.Type; +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.collection.IsMapContaining.hasEntry; +import static org.hamcrest.core.IsCollectionContaining.hasItems; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +/** + * @author aiet + */ +public class MicrometerAtlasTest { + + private AtlasConfig atlasConfig; + + @Before + public void init() { + atlasConfig = new AtlasConfig() { + + @Override + public Duration step() { + return Duration.ofSeconds(1); + } + + @Override + public String get(String k) { + return null; + } + }; + } + + @Test + public void givenCompositeRegistries_whenRecordMeter_thenAllRegistriesRecorded() { + CompositeMeterRegistry compositeRegistry = new CompositeMeterRegistry(); + + SimpleMeterRegistry oneSimpleMeter = new SimpleMeterRegistry(); + AtlasMeterRegistry atlasMeterRegistry = new AtlasMeterRegistry(atlasConfig, Clock.SYSTEM); + + compositeRegistry.add(oneSimpleMeter); + compositeRegistry.add(atlasMeterRegistry); + + compositeRegistry.gauge("baeldung.heat", 90); + + Optional oneGauge = oneSimpleMeter + .find("baeldung.heat") + .gauge(); + assertTrue(oneGauge.isPresent()); + Iterator measurements = oneGauge + .get() + .measure() + .iterator(); + + assertTrue(measurements.hasNext()); + assertThat(measurements + .next() + .getValue(), equalTo(90.00)); + + Optional atlasGauge = atlasMeterRegistry + .find("baeldung.heat") + .gauge(); + assertTrue(atlasGauge.isPresent()); + Iterator anotherMeasurements = atlasGauge + .get() + .measure() + .iterator(); + + assertTrue(anotherMeasurements.hasNext()); + assertThat(anotherMeasurements + .next() + .getValue(), equalTo(90.00)); + } + + @Test + public void givenGlobalRegistry_whenIncrementAnywhere_thenCounted() { + class CountedObject { + private CountedObject() { + Metrics + .counter("objects.instance") + .increment(1.0); + } + } + Metrics.addRegistry(new SimpleMeterRegistry()); + + Metrics + .counter("objects.instance") + .increment(); + new CountedObject(); + + Optional counterOptional = Metrics.globalRegistry + .find("objects.instance") + .counter(); + + assertTrue(counterOptional.isPresent()); + assertTrue(counterOptional + .get() + .count() == 2.0); + } + + @Test + public void givenCounter_whenIncrement_thenValueChanged() { + SimpleMeterRegistry registry = new SimpleMeterRegistry(); + Counter counter = Counter + .builder("objects.instance") + .description("indicates instance count of the object") + .tags("dev", "performance") + .register(registry); + + counter.increment(2.0); + assertTrue(counter.count() == 2); + + counter.increment(-1); + assertTrue(counter.count() == 2); + } + + @Test + public void givenTimer_whenWrapTasks_thenTimeRecorded() { + SimpleMeterRegistry registry = new SimpleMeterRegistry(); + Timer timer = registry.timer("app.event"); + timer.record(() -> { + try { + TimeUnit.MILLISECONDS.sleep(1500); + } catch (InterruptedException ignored) { + } + }); + + timer.record(3000, TimeUnit.MILLISECONDS); + + assertTrue(2 == timer.count()); + assertTrue(4510 > timer.totalTime(TimeUnit.MILLISECONDS) && 4500 <= timer.totalTime(TimeUnit.MILLISECONDS)); + } + + @Test + public void givenLongTimer_whenRunTasks_thenTimerRecorded() { + SimpleMeterRegistry registry = new SimpleMeterRegistry(); + LongTaskTimer longTaskTimer = LongTaskTimer + .builder("3rdPartyService") + .register(registry); + + long currentTaskId = longTaskTimer.start(); + try { + TimeUnit.SECONDS.sleep(2); + } catch (InterruptedException ignored) { + } + long timeElapsed = longTaskTimer.stop(currentTaskId); + + assertTrue(timeElapsed / (int) 1e9 == 2); + } + + @Test + public void givenGauge_whenMeterListSize_thenCurrentSizeMonitored() { + SimpleMeterRegistry registry = new SimpleMeterRegistry(); + List list = new ArrayList<>(4); + Gauge gauge = Gauge + .builder("cache.size", list, List::size) + .register(registry); + + assertTrue(gauge.value() == 0.0); + + list.add("1"); + assertTrue(gauge.value() == 1.0); + } + + @Test + public void givenDistributionSummary_whenRecord_thenSummarized() { + SimpleMeterRegistry registry = new SimpleMeterRegistry(); + DistributionSummary distributionSummary = DistributionSummary + .builder("request.size") + .baseUnit("bytes") + .register(registry); + distributionSummary.record(3); + distributionSummary.record(4); + distributionSummary.record(5); + + assertTrue(3 == distributionSummary.count()); + assertTrue(12 == distributionSummary.totalAmount()); + } + + @Test + public void givenTimer_whenEnrichWithQuantile_thenQuantilesComputed() { + SimpleMeterRegistry registry = new SimpleMeterRegistry(); + Timer timer = Timer + .builder("test.timer") + .quantiles(WindowSketchQuantiles + .quantiles(0.3, 0.5, 0.95) + .create()) + .register(registry); + + timer.record(2, TimeUnit.SECONDS); + timer.record(2, TimeUnit.SECONDS); + timer.record(3, TimeUnit.SECONDS); + timer.record(4, TimeUnit.SECONDS); + timer.record(8, TimeUnit.SECONDS); + timer.record(13, TimeUnit.SECONDS); + + Map quantileMap = extractTagValueMap(registry, Type.Gauge, 1e9); + assertThat(quantileMap, allOf(hasEntry("quantile=0.3", 2), hasEntry("quantile=0.5", 3), hasEntry("quantile=0.95", 8))); + } + + private Map extractTagValueMap(MeterRegistry registry, Type meterType, double valueDivisor) { + return registry + .getMeters() + .stream() + .filter(meter -> meter.getType() == meterType) + .collect(Collectors.toMap(meter -> { + Tag tag = meter + .getId() + .getTags() + .iterator() + .next(); + return tag.getKey() + "=" + tag.getValue(); + }, meter -> (int) (meter + .measure() + .iterator() + .next() + .getValue() / valueDivisor))); + } + + @Test + public void givenDistributionSummary_whenEnrichWithHistograms_thenDataAggregated() { + SimpleMeterRegistry registry = new SimpleMeterRegistry(); + DistributionSummary hist = DistributionSummary + .builder("summary") + .histogram(Histogram.linear(0, 10, 5)) + .register(registry); + + hist.record(3); + hist.record(8); + hist.record(20); + hist.record(40); + hist.record(13); + hist.record(26); + + Map histograms = extractTagValueMap(registry, Type.Counter, 1.0); + + assertThat(histograms, allOf(hasEntry("bucket=0.0", 0), hasEntry("bucket=10.0", 2), hasEntry("bucket=20.0", 2), hasEntry("bucket=30.0", 1), hasEntry("bucket=40.0", 1), hasEntry("bucket=Infinity", 0))); + } + + @Test + public void givenTimer_whenEnrichWithTimescaleHistogram_thenTimeScaleDataCollected() { + SimpleMeterRegistry registry = new SimpleMeterRegistry(); + Timer timer = Timer + .builder("timer") + .histogram(Histogram.linearTime(TimeUnit.MILLISECONDS, 0, 200, 3)) + .register(registry); + + timer.record(1000, TimeUnit.MILLISECONDS); + timer.record(23, TimeUnit.MILLISECONDS); + timer.record(450, TimeUnit.MILLISECONDS); + timer.record(341, TimeUnit.MILLISECONDS); + timer.record(500, TimeUnit.MILLISECONDS); + + Map histograms = extractTagValueMap(registry, Type.Counter, 1.0); + + assertThat(histograms, allOf(hasEntry("bucket=0.0", 0), hasEntry("bucket=2.0E8", 1), hasEntry("bucket=4.0E8", 1), hasEntry("bucket=Infinity", 3))); + + } + +} diff --git a/muleesb/.gitignore b/muleesb/.gitignore new file mode 100644 index 0000000000..541f92c42e --- /dev/null +++ b/muleesb/.gitignore @@ -0,0 +1 @@ +# Add any directories, files, or patterns you don't want to be tracked by version control \ No newline at end of file diff --git a/muleesb/.mule/objectstore/b2fe1a90-c473-11e7-8eb5-98e7f44e8ac8/partition-descriptor b/muleesb/.mule/objectstore/b2fe1a90-c473-11e7-8eb5-98e7f44e8ac8/partition-descriptor new file mode 100644 index 0000000000..0b8060f303 --- /dev/null +++ b/muleesb/.mule/objectstore/b2fe1a90-c473-11e7-8eb5-98e7f44e8ac8/partition-descriptor @@ -0,0 +1 @@ +DEFAULT_PARTITION \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.rse.core/.log b/muleesb/.mule/queue-tx-log/tx1.log similarity index 100% rename from .metadata/.plugins/org.eclipse.rse.core/.log rename to muleesb/.mule/queue-tx-log/tx1.log diff --git a/.metadata/.plugins/org.eclipse.rse.core/initializerMarks/org.eclipse.rse.internal.core.RSELocalConnectionInitializer.mark b/muleesb/.mule/queue-tx-log/tx2.log similarity index 100% rename from .metadata/.plugins/org.eclipse.rse.core/initializerMarks/org.eclipse.rse.internal.core.RSELocalConnectionInitializer.mark rename to muleesb/.mule/queue-tx-log/tx2.log diff --git a/.metadata/.plugins/org.eclipse.rse.ui/.log b/muleesb/.mule/queue-xa-tx-log/tx1.log similarity index 100% rename from .metadata/.plugins/org.eclipse.rse.ui/.log rename to muleesb/.mule/queue-xa-tx-log/tx1.log diff --git a/spring-rest-angular/src/main/webapp/resources/styles/style.css b/muleesb/.mule/queue-xa-tx-log/tx2.log similarity index 100% rename from spring-rest-angular/src/main/webapp/resources/styles/style.css rename to muleesb/.mule/queue-xa-tx-log/tx2.log diff --git a/muleesb/mule-project.xml b/muleesb/mule-project.xml new file mode 100644 index 0000000000..0d522b0141 --- /dev/null +++ b/muleesb/mule-project.xml @@ -0,0 +1,5 @@ + + + muleesb + + diff --git a/muleesb/pom.xml b/muleesb/pom.xml new file mode 100644 index 0000000000..2c88bf83da --- /dev/null +++ b/muleesb/pom.xml @@ -0,0 +1,214 @@ + + + + 4.0.0 + com.mycompany + muleesb + 1.0.0-SNAPSHOT + mule + Mule muleesb Application + + + UTF-8 + UTF-8 + + 3.8.1 + 1.2 + 1.3.6 + 3.9.0 + + + + + + org.mule.tools.maven + mule-app-maven-plugin + ${mule.tools.version} + true + + true + + + + org.mule.tools + muleesb-maven-plugin + 1.0 + + 3.7.0 + /home/abir/AnypointStudio/workspace/variablescopetest + + + + deploy + + start + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + + + add-resource + generate-resources + + add-resource + + + + + src/main/app/ + + + mappings/ + + + src/main/api/ + + + + + + + + com.mulesoft.munit.tools + munit-maven-plugin + ${munit.version} + + + test + test + + test + + + + + + true + + html + + + + + + + + src/test/munit + + + src/test/resources + + + + + + + + + org.mule.modules + mule-module-spring-config + ${mule.version} + provided + + + + org.mule.transports + mule-transport-file + ${mule.version} + provided + + + org.mule.transports + mule-transport-http + ${mule.version} + provided + + + org.mule.transports + mule-transport-jdbc + ${mule.version} + provided + + + org.mule.transports + mule-transport-jms + ${mule.version} + provided + + + org.mule.transports + mule-transport-vm + ${mule.version} + provided + + + + org.mule.modules + mule-module-scripting + ${mule.version} + provided + + + org.mule.modules + mule-module-xml + ${mule.version} + provided + + + + org.mule.tests + mule-tests-functional + ${mule.version} + test + + + org.mule.modules + mule-module-apikit + ${mule.version} + provided + + + com.mulesoft.munit + mule-munit-support + ${mule.munit.support.version} + test + + + com.mulesoft.munit + munit-runner + ${munit.version} + test + + + + + + Central + Central + http://repo1.maven.org/maven2/ + default + + + mulesoft-releases + MuleSoft Releases Repository + http://repository.mulesoft.org/releases/ + default + + + + + mulesoft-release + mulesoft release repository + default + http://repository.mulesoft.org/releases/ + + false + + + + diff --git a/muleesb/src/main/app/mule-app.properties b/muleesb/src/main/app/mule-app.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/muleesb/src/main/app/mule-deploy.properties b/muleesb/src/main/app/mule-deploy.properties new file mode 100644 index 0000000000..07eabe9cc6 --- /dev/null +++ b/muleesb/src/main/app/mule-deploy.properties @@ -0,0 +1,6 @@ +#** GENERATED CONTENT ** Mule Application Deployment Descriptor +#Mon Nov 06 15:54:37 BDT 2017 +redeployment.enabled=true +encoding=UTF-8 +domain=default +config.resources=variablescopetest.xml diff --git a/muleesb/src/main/app/variablescopetest.xml b/muleesb/src/main/app/variablescopetest.xml new file mode 100644 index 0000000000..518b901084 --- /dev/null +++ b/muleesb/src/main/app/variablescopetest.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/muleesb/src/main/java/com/baeldung/transformer/FromFlow2Component.java b/muleesb/src/main/java/com/baeldung/transformer/FromFlow2Component.java new file mode 100644 index 0000000000..0e180062a7 --- /dev/null +++ b/muleesb/src/main/java/com/baeldung/transformer/FromFlow2Component.java @@ -0,0 +1,18 @@ +package com.baeldung.transformer; + +import org.mule.api.MuleEventContext; +import org.mule.api.MuleMessage; +import org.mule.api.lifecycle.Callable; + +public class FromFlow2Component implements Callable { + + @Override + public Object onCall(MuleEventContext eventContext) throws Exception { + + MuleMessage message = eventContext.getMessage(); + message.setPayload("Converted in flow 2"); + + return message; + } + +} diff --git a/muleesb/src/main/java/com/baeldung/transformer/InitializationTransformer.java b/muleesb/src/main/java/com/baeldung/transformer/InitializationTransformer.java new file mode 100644 index 0000000000..1e1ad15be8 --- /dev/null +++ b/muleesb/src/main/java/com/baeldung/transformer/InitializationTransformer.java @@ -0,0 +1,29 @@ +package com.baeldung.transformer; + +import org.mule.api.MuleMessage; +import org.mule.api.transformer.TransformerException; +import org.mule.api.transport.PropertyScope; +import org.mule.transformer.AbstractMessageTransformer; + +public class InitializationTransformer extends AbstractMessageTransformer { + + @Override + public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException { + // TODO Auto-generated method stub + + String payload = null; + + try { + payload = message.getPayloadAsString(); + }catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("Logged Payload: "+payload); + message.setPayload("Payload from Initialization"); + message.setProperty("outboundKey", "outboundpropertyvalue",PropertyScope.OUTBOUND); + + + return message; + } +} \ No newline at end of file diff --git a/muleesb/src/main/java/com/baeldung/transformer/InvokingMessageComponent.java b/muleesb/src/main/java/com/baeldung/transformer/InvokingMessageComponent.java new file mode 100644 index 0000000000..105522e5b4 --- /dev/null +++ b/muleesb/src/main/java/com/baeldung/transformer/InvokingMessageComponent.java @@ -0,0 +1,16 @@ +package com.baeldung.transformer; + +import org.mule.api.MuleMessage; +import org.mule.api.transformer.TransformerException; +import org.mule.transformer.AbstractMessageTransformer; + +public class InvokingMessageComponent extends AbstractMessageTransformer { + + @Override + public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException { + // TODO Auto-generated method stub + String InboundProp = (String) message.getInboundProperty("outboundKey"); + System.out.println("InboundProp:" + InboundProp); + return InboundProp; + } +} \ No newline at end of file diff --git a/muleesb/src/main/resources/log4j2.xml b/muleesb/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..98c4b02433 --- /dev/null +++ b/muleesb/src/main/resources/log4j2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/muleesb/src/test/munit/variablescopetest-test-suite.xml b/muleesb/src/test/munit/variablescopetest-test-suite.xml new file mode 100644 index 0000000000..43e410a327 --- /dev/null +++ b/muleesb/src/test/munit/variablescopetest-test-suite.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/muleesb/src/test/resources/log4j2-test.xml b/muleesb/src/test/resources/log4j2-test.xml new file mode 100644 index 0000000000..6351ae041c --- /dev/null +++ b/muleesb/src/test/resources/log4j2-test.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mustache/README.md b/mustache/README.md index b616b2df8a..fa41eb4f4d 100644 --- a/mustache/README.md +++ b/mustache/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: -[Introduction to Mustache](http://www.baeldung.com/mustache) +- [Introduction to Mustache](http://www.baeldung.com/mustache) +- [Guide to Mustache with Spring Boot](http://www.baeldung.com/spring-boot-mustache) diff --git a/mustache/pom.xml b/mustache/pom.xml index d5d80b58e9..230aeecd60 100644 --- a/mustache/pom.xml +++ b/mustache/pom.xml @@ -8,9 +8,11 @@ mustache - com.baeldung - parent-modules - 1.0.0-SNAPSHOT + org.springframework.boot + spring-boot-starter-parent + 1.5.4.RELEASE + + @@ -32,6 +34,28 @@ log4j ${log4j.version} + + + org.springframework.boot + spring-boot-starter-mustache + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.webjars + bootstrap + 3.3.7 + + + org.fluttercode.datafactory + datafactory + 0.8 + + junit junit @@ -41,6 +65,101 @@ + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + **/AutoconfigurationTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + autoconfiguration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*LiveTest.java + **/*IntegrationTest.java + + + **/AutoconfigurationTest.java + + + + + + + json + + + + + + + + 0.9.2 3.7.0 @@ -52,6 +171,8 @@ 3.6.0 2.19.1 + + 1.8 \ No newline at end of file diff --git a/mustache/src/main/java/com/baeldung/springmustache/SpringMustacheApplication.java b/mustache/src/main/java/com/baeldung/springmustache/SpringMustacheApplication.java new file mode 100644 index 0000000000..8cdf89d08a --- /dev/null +++ b/mustache/src/main/java/com/baeldung/springmustache/SpringMustacheApplication.java @@ -0,0 +1,32 @@ +package com.baeldung.springmustache; + +import com.samskivert.mustache.Mustache; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.mustache.MustacheEnvironmentCollector; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.core.env.Environment; + +@SpringBootApplication +@ComponentScan(basePackages = {"com.baeldung"}) +public class SpringMustacheApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringMustacheApplication.class, args); + } + + @Bean + public Mustache.Compiler mustacheCompiler(Mustache.TemplateLoader templateLoader, Environment environment) { + + MustacheEnvironmentCollector collector = new MustacheEnvironmentCollector(); + collector.setEnvironment(environment); + + return Mustache.compiler() + .defaultValue("Some Default Value") + .withLoader(templateLoader) + .withCollector(collector); + + } +} + diff --git a/mustache/src/main/java/com/baeldung/springmustache/controller/ArticleController.java b/mustache/src/main/java/com/baeldung/springmustache/controller/ArticleController.java new file mode 100644 index 0000000000..880fb337fd --- /dev/null +++ b/mustache/src/main/java/com/baeldung/springmustache/controller/ArticleController.java @@ -0,0 +1,42 @@ +package com.baeldung.springmustache.controller; + +import com.baeldung.springmustache.model.Article; +import org.fluttercode.datafactory.impl.DataFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.ModelAndView; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +@Controller +public class ArticleController { + + @GetMapping("/article") + public ModelAndView displayArticle(Map model) { + + List
    articles = IntStream.range(0, 10) + .mapToObj(i -> generateArticle("Article Title " + i)) + .collect(Collectors.toList()); + + model.put("articles", articles); + + return new ModelAndView("index", model); + } + + private Article generateArticle(String title) { + Article article = new Article(); + DataFactory factory = new DataFactory(); + article.setTitle(title); + article.setBody( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur faucibus tempor diam. In molestie arcu eget ante facilisis sodales. Maecenas porta tellus sapien, eget rutrum nisi blandit in. Mauris tempor auctor ante, ut blandit velit venenatis id. Ut varius, augue aliquet feugiat congue, arcu ipsum finibus purus, dapibus semper velit sapien venenatis magna. Nunc quam ex, aliquet at rutrum sed, vestibulum quis libero. In laoreet libero cursus maximus vulputate. Nullam in fermentum sem. Duis aliquam ullamcorper dui, et dictum justo placerat id. Aliquam pretium orci quis sapien convallis, non blandit est tempus."); + article.setPublishDate(factory.getBirthDate().toString()); + article.setAuthor(factory.getName()); + return article; + } +} + + diff --git a/mustache/src/main/java/com/baeldung/springmustache/model/Article.java b/mustache/src/main/java/com/baeldung/springmustache/model/Article.java new file mode 100644 index 0000000000..78b08f877f --- /dev/null +++ b/mustache/src/main/java/com/baeldung/springmustache/model/Article.java @@ -0,0 +1,41 @@ +package com.baeldung.springmustache.model; + +public class Article { + private String title; + private String body; + private String author; + private String publishDate; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getPublishDate() { + return publishDate; + } + + public void setPublishDate(String publishDate) { + this.publishDate = publishDate; + } + +} diff --git a/mustache/src/main/resources/application.properties b/mustache/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/mustache/src/main/resources/templates/error/error.html b/mustache/src/main/resources/templates/error/error.html new file mode 100644 index 0000000000..fa29db41c4 --- /dev/null +++ b/mustache/src/main/resources/templates/error/error.html @@ -0,0 +1,9 @@ + + + + + + Something went wrong: {{status}} {{error}} + + + \ No newline at end of file diff --git a/mustache/src/main/resources/templates/index.html b/mustache/src/main/resources/templates/index.html new file mode 100644 index 0000000000..bda60f9d8f --- /dev/null +++ b/mustache/src/main/resources/templates/index.html @@ -0,0 +1,9 @@ +{{>layout/header}} + +
    {{>layout/article}}
    + + + + +{{>layout/footer}} diff --git a/mustache/src/main/resources/templates/layout/article.html b/mustache/src/main/resources/templates/layout/article.html new file mode 100644 index 0000000000..9d573580d3 --- /dev/null +++ b/mustache/src/main/resources/templates/layout/article.html @@ -0,0 +1,8 @@ +
    + {{#articles}} +

    {{title}}

    +

    {{publishDate}}

    +

    {{author}}

    +

    {{body}}

    + {{/articles}} +
    \ No newline at end of file diff --git a/mustache/src/main/resources/templates/layout/footer.html b/mustache/src/main/resources/templates/layout/footer.html new file mode 100644 index 0000000000..04f34cac54 --- /dev/null +++ b/mustache/src/main/resources/templates/layout/footer.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/mustache/src/main/resources/templates/layout/header.html b/mustache/src/main/resources/templates/layout/header.html new file mode 100644 index 0000000000..d203ef800b --- /dev/null +++ b/mustache/src/main/resources/templates/layout/header.html @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/mustache/src/test/java/com/baeldung/mustache/TodoMustacheServiceTest.java b/mustache/src/test/java/com/baeldung/mustache/TodoMustacheServiceTest.java index 17a59aa6a1..0df2f7f8a4 100644 --- a/mustache/src/test/java/com/baeldung/mustache/TodoMustacheServiceTest.java +++ b/mustache/src/test/java/com/baeldung/mustache/TodoMustacheServiceTest.java @@ -1,100 +1,98 @@ package com.baeldung.mustache; -import static org.assertj.core.api.Assertions.assertThat; +import com.baeldung.mustache.model.Todo; +import com.github.mustachejava.Mustache; +import org.junit.Test; import java.io.IOException; import java.io.StringWriter; import java.time.Instant; -import java.time.LocalDateTime; -import java.time.temporal.TemporalUnit; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Function; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; -import com.baeldung.mustache.model.Todo; -import com.github.mustachejava.Mustache; public class TodoMustacheServiceTest { - private String executeTemplate(Mustache m, Map context) throws IOException{ + private String executeTemplate(Mustache m, Map context) throws IOException { StringWriter writer = new StringWriter(); m.execute(writer, context).flush(); return writer.toString(); } - - private String executeTemplate(Mustache m, Todo todo) throws IOException{ + + private String executeTemplate(Mustache m, Todo todo) throws IOException { StringWriter writer = new StringWriter(); m.execute(writer, todo).flush(); return writer.toString(); } - + @Test - public void givenTodoObject_whenGetHtml_thenSuccess() throws IOException{ + public void givenTodoObject_whenGetHtml_thenSuccess() throws IOException { Todo todo = new Todo("Todo 1", "Todo description"); Mustache m = MustacheUtil.getMustacheFactory().compile("todo.mustache"); Map context = new HashMap<>(); context.put("todo", todo); - + String expected = "

    Todo 1

    "; assertThat(executeTemplate(m, todo)).contains(expected); } - + @Test - public void givenNullTodoObject_whenGetHtml_thenEmptyHtml() throws IOException{ + public void givenNullTodoObject_whenGetHtml_thenEmptyHtml() throws IOException { Mustache m = MustacheUtil.getMustacheFactory().compile("todo-section.mustache"); Map context = new HashMap<>(); assertThat(executeTemplate(m, context)).isEmpty(); } - + @Test - public void givenTodoList_whenGetHtml_thenSuccess() throws IOException{ + public void givenTodoList_whenGetHtml_thenSuccess() throws IOException { Mustache m = MustacheUtil.getMustacheFactory().compile("todos.mustache"); - + List todos = Arrays.asList( - new Todo("Todo 1", "Todo description"), - new Todo("Todo 2", "Todo description another"), - new Todo("Todo 3", "Todo description another") - ); + new Todo("Todo 1", "Todo description"), + new Todo("Todo 2", "Todo description another"), + new Todo("Todo 3", "Todo description another") + ); Map context = new HashMap<>(); context.put("todos", todos); - + assertThat(executeTemplate(m, context)) .contains("

    Todo 1

    ") .contains("

    Todo 2

    ") .contains("

    Todo 3

    "); } - + @Test - public void givenEmptyList_whenGetHtml_thenEmptyHtml() throws IOException{ + public void givenEmptyList_whenGetHtml_thenEmptyHtml() throws IOException { Mustache m = MustacheUtil.getMustacheFactory().compile("todos.mustache"); - + Map context = new HashMap<>(); - assertThat(executeTemplate(m, context)).isEmpty();; + assertThat(executeTemplate(m, context)).isEmpty(); + ; } - + @Test - public void givenEmptyList_whenGetHtmlUsingInvertedSection_thenHtml() throws IOException{ + public void givenEmptyList_whenGetHtmlUsingInvertedSection_thenHtml() throws IOException { Mustache m = MustacheUtil.getMustacheFactory().compile("todos-inverted-section.mustache"); - + Map context = new HashMap<>(); assertThat(executeTemplate(m, context).trim()).isEqualTo("

    No todos!

    "); } - + @Test - public void givenTodoList_whenGetHtmlUsingLamdba_thenHtml() throws IOException{ + public void givenTodoList_whenGetHtmlUsingLamdba_thenHtml() throws IOException { Mustache m = MustacheUtil.getMustacheFactory().compile("todos-lambda.mustache"); List todos = Arrays.asList( - new Todo("Todo 1", "Todo description"), - new Todo("Todo 2", "Todo description another"), - new Todo("Todo 3", "Todo description another") - ); + new Todo("Todo 1", "Todo description"), + new Todo("Todo 2", "Todo description another"), + new Todo("Todo 3", "Todo description another") + ); todos.get(2).setDone(true); todos.get(2).setCompletedOn(Date.from(Instant.now().plusSeconds(300))); - + Map context = new HashMap<>(); context.put("todos", todos); assertThat(executeTemplate(m, context).trim()).contains("Done 5 minutes ago"); diff --git a/mustache/src/test/java/com/baeldung/springmustache/SpringMustacheApplicationIntegrationTest.java b/mustache/src/test/java/com/baeldung/springmustache/SpringMustacheApplicationIntegrationTest.java new file mode 100644 index 0000000000..1eecf58986 --- /dev/null +++ b/mustache/src/test/java/com/baeldung/springmustache/SpringMustacheApplicationIntegrationTest.java @@ -0,0 +1,30 @@ +package com.baeldung.springmustache; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +public class SpringMustacheApplicationIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void givenIndexPageWhenContainsArticleThenTrue() { + + ResponseEntity entity = this.restTemplate.getForEntity("/article", String.class); + + Assert.assertTrue(entity.getStatusCode().equals(HttpStatus.OK)); + Assert.assertTrue(entity.getBody().contains("Article Title 0")); + } + +} diff --git a/noexception/README.md b/noexception/README.md index d840191369..9dd4c11190 100644 --- a/noexception/README.md +++ b/noexception/README.md @@ -1,2 +1,2 @@ ### Relevant Articles: -- [Introduction to NoException](http://www.baeldung.com/intrduction-to-noexception) +- [Introduction to NoException](http://www.baeldung.com/introduction-to-noexception) diff --git a/osgi/osgi-intro-sample-activator/pom.xml b/osgi/osgi-intro-sample-activator/pom.xml new file mode 100644 index 0000000000..1584913627 --- /dev/null +++ b/osgi/osgi-intro-sample-activator/pom.xml @@ -0,0 +1,55 @@ + + + + + + osgi-intro + com.baeldung + 1.0-SNAPSHOT + + 4.0.0 + + + bundle + + osgi-intro-sample-activator + + + + org.osgi + org.osgi.core + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.groupId}.${project.artifactId} + ${project.artifactId} + ${project.version} + + + com.baeldung.osgi.sample.activator.HelloWorld + + + + com.baeldung.osgi.sample.activator + + + + + + + + diff --git a/osgi/osgi-intro-sample-activator/src/main/java/com/baeldung/osgi/sample/activator/HelloWorld.java b/osgi/osgi-intro-sample-activator/src/main/java/com/baeldung/osgi/sample/activator/HelloWorld.java new file mode 100644 index 0000000000..72fe624bac --- /dev/null +++ b/osgi/osgi-intro-sample-activator/src/main/java/com/baeldung/osgi/sample/activator/HelloWorld.java @@ -0,0 +1,16 @@ +package com.baeldung.osgi.sample.activator; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class HelloWorld implements BundleActivator { + + public void start(BundleContext ctx) { + System.out.println("Hello World."); + } + + public void stop(BundleContext bundleContext) { + System.out.println("Goodbye World."); + } + +} \ No newline at end of file diff --git a/osgi/osgi-intro-sample-client/pom.xml b/osgi/osgi-intro-sample-client/pom.xml new file mode 100644 index 0000000000..4096674d7d --- /dev/null +++ b/osgi/osgi-intro-sample-client/pom.xml @@ -0,0 +1,49 @@ + + + + osgi-intro + com.baeldung + 1.0-SNAPSHOT + + 4.0.0 + + + osgi-intro-sample-client + + bundle + + + + com.baeldung + osgi-intro-sample-service + 1.0-SNAPSHOT + + + org.osgi + org.osgi.core + + + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.groupId}.${project.artifactId} + ${project.artifactId} + ${project.version} + com.baeldung.osgi.sample.client.Client + + com.baeldung.osgi.sample.client + + + + + + + + \ No newline at end of file diff --git a/osgi/osgi-intro-sample-client/src/main/java/com/baeldung/osgi/sample/client/Client.java b/osgi/osgi-intro-sample-client/src/main/java/com/baeldung/osgi/sample/client/Client.java new file mode 100644 index 0000000000..a82ed63fa7 --- /dev/null +++ b/osgi/osgi-intro-sample-client/src/main/java/com/baeldung/osgi/sample/client/Client.java @@ -0,0 +1,44 @@ +package com.baeldung.osgi.sample.client; + +import com.baeldung.osgi.sample.service.definition.Greeter; +import org.osgi.framework.*; + +public class Client implements BundleActivator, ServiceListener { + + private BundleContext ctx; + private ServiceReference serviceReference; + + public void start(BundleContext ctx) { + this.ctx = ctx; + try { + ctx.addServiceListener(this, "(objectclass=" + Greeter.class.getName() + ")"); + } catch (InvalidSyntaxException ise) { + ise.printStackTrace(); + } + } + + public void stop(BundleContext bundleContext) { + if (serviceReference != null) { + ctx.ungetService(serviceReference); + } + this.ctx = null; + } + + public void serviceChanged(ServiceEvent serviceEvent) { + int type = serviceEvent.getType(); + switch (type) { + case (ServiceEvent.REGISTERED): + System.out.println("Notification of service registered."); + serviceReference = serviceEvent.getServiceReference(); + Greeter service = (Greeter) (ctx.getService(serviceReference)); + System.out.println(service.sayHiTo("John")); + break; + case (ServiceEvent.UNREGISTERING): + System.out.println("Notification of service unregistered."); + ctx.ungetService(serviceEvent.getServiceReference()); + break; + default: + break; + } + } +} diff --git a/osgi/osgi-intro-sample-service/pom.xml b/osgi/osgi-intro-sample-service/pom.xml new file mode 100644 index 0000000000..cbc660bb74 --- /dev/null +++ b/osgi/osgi-intro-sample-service/pom.xml @@ -0,0 +1,46 @@ + + + + + + osgi-intro + com.baeldung + 1.0-SNAPSHOT + + 4.0.0 + + osgi-intro-sample-service + + + bundle + + + + org.osgi + org.osgi.core + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.groupId}.${project.artifactId} + ${project.artifactId} + ${project.version} + com.baeldung.osgi.sample.service.implementation.GreeterImpl + com.baeldung.osgi.sample.service.implementation + com.baeldung.osgi.sample.service.definition + + + + + + + \ No newline at end of file diff --git a/osgi/osgi-intro-sample-service/src/main/java/com/baeldung/osgi/sample/service/definition/Greeter.java b/osgi/osgi-intro-sample-service/src/main/java/com/baeldung/osgi/sample/service/definition/Greeter.java new file mode 100644 index 0000000000..f1e82a3465 --- /dev/null +++ b/osgi/osgi-intro-sample-service/src/main/java/com/baeldung/osgi/sample/service/definition/Greeter.java @@ -0,0 +1,7 @@ +package com.baeldung.osgi.sample.service.definition; + +public interface Greeter { + + public String sayHiTo(String name); + +} diff --git a/osgi/osgi-intro-sample-service/src/main/java/com/baeldung/osgi/sample/service/implementation/GreeterImpl.java b/osgi/osgi-intro-sample-service/src/main/java/com/baeldung/osgi/sample/service/implementation/GreeterImpl.java new file mode 100644 index 0000000000..48e26e3e6b --- /dev/null +++ b/osgi/osgi-intro-sample-service/src/main/java/com/baeldung/osgi/sample/service/implementation/GreeterImpl.java @@ -0,0 +1,30 @@ +package com.baeldung.osgi.sample.service.implementation; + +import com.baeldung.osgi.sample.service.definition.Greeter; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; + +import java.util.Hashtable; + +public class GreeterImpl implements Greeter, BundleActivator { + + private ServiceReference reference; + private ServiceRegistration registration; + + @Override public String sayHiTo(String name) { + return "Hello " + name; + } + + @Override public void start(BundleContext context) throws Exception { + System.out.println("Registering service."); + registration = context.registerService(Greeter.class, new GreeterImpl(), new Hashtable()); + reference = registration.getReference(); + } + + @Override public void stop(BundleContext context) throws Exception { + System.out.println("Unregistering service."); + registration.unregister(); + } +} diff --git a/osgi/pom.xml b/osgi/pom.xml new file mode 100644 index 0000000000..e6ef9c3192 --- /dev/null +++ b/osgi/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + osgi-intro + pom + 1.0-SNAPSHOT + + osgi-intro-sample-activator + osgi-intro-sample-service + osgi-intro-sample-client + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + .. + + + + + + + ${project.groupId} + osgi-intro-client + ${project.version} + + + + ${project.groupId} + osgi-intro-service + ${project.version} + + + + ${project.groupId} + osgi-intro-gxyz + ${project.version} + + + + ${project.groupId} + osgi-intro-mapquest + ${project.version} + + + + com.squareup.okhttp3 + okhttp + 3.9.0 + + + javax.json + javax.json-api + 1.1 + + + org.glassfish + javax.json + 1.1 + + + org.osgi + org.osgi.core + 6.0.0 + provided + + + + + + + + + org.apache.felix + maven-bundle-plugin + 3.3.0 + true + + + + + + \ No newline at end of file diff --git a/osgi/readme.md b/osgi/readme.md new file mode 100644 index 0000000000..ea4a411c7b --- /dev/null +++ b/osgi/readme.md @@ -0,0 +1,91 @@ +OSGi +==== + +Info +--- + +com.baeldung.osgi +com.baeldung.osgi.sample.activator + +Apache Felix +--- + + +### Start + +Download Apache Felix Framework Distribution +from +org.apache.felix.main.distribution-5.6.8 + +No! The Apache Karaf container is best. +Download it from: + +Download a binary distribution and unzip wherever you prefer. + +Then run + + bin\karaf.bat start + + +Unzip, pay attention to the files not being clipped(!). + + system:exit + +exit! + + shutdown -h + +or `^D` + +### clean start + +full clean, remove "data directory " + +or... + + bin\karaf.bat clean + + bin\start.bat clean + +### run mode + +can be launched in + +- the "regular" mode starts Apache Karaf in foreground, including the shell console. +- the "server" mode starts Apache Karaf in foreground, without the shell console. +- the "background" mode starts Apache Karaf in background. + +### Logging + +https://karaf.apache.org/manual/latest/#_log + +can be logged to console + + +### Bundle deploy + + bundle:install mvn:com.baeldung/osgi-intro-sample-activator/1.0-SNAPSHOT + + install mvn:com.baeldung/osgi-intro-sample-service/1.0-SNAPSHOT + install mvn:com.baeldung/osgi-intro-sample-client/1.0-SNAPSHOT + +Eclipse's Equinox +==== + +Eclipse's OSGi platform +http://www.eclipse.org/equinox/ + +http://www.eclipse.org/equinox/documents/quickstart-framework.php + +click on "download" + +Latest Release +Oxygen.1 Wed, 6 Sep 2017 -- 17:00 (-0400) + +org.eclipse.osgi_3.12.1.v20170821-1548.jar + + = = NOT GOOD = = + + + + diff --git a/parent-boot-4/README.md b/parent-boot-4/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/parent-boot-4/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/parent-boot-4/pom.xml b/parent-boot-4/pom.xml index 2af36e9365..608e57ddaf 100644 --- a/parent-boot-4/pom.xml +++ b/parent-boot-4/pom.xml @@ -63,7 +63,7 @@ **/JdbcTest.java **/*LiveTest.java - true + diff --git a/parent-boot-5/README.md b/parent-boot-5/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/parent-boot-5/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/parent-boot-5/pom.xml b/parent-boot-5/pom.xml index 57e9ed3c67..2fa397f298 100644 --- a/parent-boot-5/pom.xml +++ b/parent-boot-5/pom.xml @@ -65,7 +65,6 @@ **/*EntryPointsTest.java **/*LiveTest.java - true diff --git a/patterns/README.md b/patterns/README.md index bcd54a64b1..67d84154cb 100644 --- a/patterns/README.md +++ b/patterns/README.md @@ -1,3 +1,4 @@ ###Relevant Articles: - [A Guide to the Front Controller Pattern in Java](http://www.baeldung.com/java-front-controller-pattern) - [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java) +- [Implementing the Template Method Pattern in Java](http://www.baeldung.com/template-method-pattern-in-java) diff --git a/patterns/behavioral-patterns/pom.xml b/patterns/behavioral-patterns/pom.xml new file mode 100644 index 0000000000..3c40520ce1 --- /dev/null +++ b/patterns/behavioral-patterns/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + com.baeldung.pattern.templatemethod + pattern.templatemethod + 1.0 + jar + + com.baeldung.patterns + patterns-parent + 1.0.0-SNAPSHOT + .. + + + + + junit + junit + 4.12 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + + + + UTF-8 + 1.8 + 1.8 + + \ No newline at end of file diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/application/Application.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/application/Application.java new file mode 100644 index 0000000000..9ab34c3cd8 --- /dev/null +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/application/Application.java @@ -0,0 +1,21 @@ +package com.baeldung.pattern.templatemethod.application; + +import com.baeldung.pattern.templatemethod.model.Computer; +import com.baeldung.pattern.templatemethod.model.StandardComputer; +import com.baeldung.pattern.templatemethod.model.HighEndComputer; +import com.baeldung.pattern.templatemethod.model.ComputerBuilder; +import com.baeldung.pattern.templatemethod.model.HighEndComputerBuilder; +import com.baeldung.pattern.templatemethod.model.StandardComputerBuilder; + +public class Application { + + public static void main(String[] args) { + ComputerBuilder standardComputerBuilder = new StandardComputerBuilder(); + Computer standardComputer = standardComputerBuilder.buildComputer(); + standardComputer.getComputerParts().forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v)); + + ComputerBuilder highEndComputerBuilder = new HighEndComputerBuilder(); + Computer highEndComputer = highEndComputerBuilder.buildComputer(); + highEndComputer.getComputerParts().forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v)); + } +} diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/Computer.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/Computer.java new file mode 100644 index 0000000000..1419398f62 --- /dev/null +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/Computer.java @@ -0,0 +1,17 @@ +package com.baeldung.pattern.templatemethod.model; + +import java.util.HashMap; +import java.util.Map; + +public class Computer { + + private Map computerParts = new HashMap<>(); + + public Computer(Map computerParts) { + this.computerParts = computerParts; + } + + public Map getComputerParts() { + return computerParts; + } +} diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/ComputerBuilder.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/ComputerBuilder.java new file mode 100644 index 0000000000..515a6940f5 --- /dev/null +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/ComputerBuilder.java @@ -0,0 +1,38 @@ +package com.baeldung.pattern.templatemethod.model; + +import com.baeldung.pattern.templatemethod.model.Computer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public abstract class ComputerBuilder { + + protected Map computerParts = new HashMap<>(); + protected List motherboardSetupStatus = new ArrayList<>(); + + public final Computer buildComputer() { + addMotherboard(); + setupMotherboard(); + addProcessor(); + return getComputer(); + } + + public abstract void addMotherboard(); + + public abstract void setupMotherboard(); + + public abstract void addProcessor(); + + public List getMotherboardSetupStatus() { + return motherboardSetupStatus; + } + + public Map getComputerParts() { + return computerParts; + } + + private Computer getComputer() { + return new Computer(computerParts); + } +} diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputer.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputer.java new file mode 100644 index 0000000000..0684b1b233 --- /dev/null +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputer.java @@ -0,0 +1,11 @@ +package com.baeldung.pattern.templatemethod.model; + +import com.baeldung.pattern.templatemethod.model.Computer; +import java.util.Map; + +public class HighEndComputer extends Computer { + + public HighEndComputer(Map computerParts) { + super(computerParts); + } +} diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputerBuilder.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputerBuilder.java new file mode 100644 index 0000000000..c992aa2bff --- /dev/null +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputerBuilder.java @@ -0,0 +1,21 @@ +package com.baeldung.pattern.templatemethod.model; + +public class HighEndComputerBuilder extends ComputerBuilder { + + @Override + public void addMotherboard() { + computerParts.put("Motherboard", "High-end Motherboard"); + } + + @Override + public void setupMotherboard() { + motherboardSetupStatus.add("Screwing the high-end motherboard to the case."); + motherboardSetupStatus.add("Pluging in the power supply connectors."); + motherboardSetupStatus.forEach(step -> System.out.println(step)); + } + + @Override + public void addProcessor() { + computerParts.put("Processor", "High-end Processor"); + } +} diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputer.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputer.java new file mode 100644 index 0000000000..4e1d857016 --- /dev/null +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputer.java @@ -0,0 +1,11 @@ +package com.baeldung.pattern.templatemethod.model; + +import com.baeldung.pattern.templatemethod.model.Computer; +import java.util.Map; + +public class StandardComputer extends Computer { + + public StandardComputer(Map computerParts) { + super(computerParts); + } +} diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputerBuilder.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputerBuilder.java new file mode 100644 index 0000000000..cc81dddc1b --- /dev/null +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputerBuilder.java @@ -0,0 +1,21 @@ +package com.baeldung.pattern.templatemethod.model; + +public class StandardComputerBuilder extends ComputerBuilder { + + @Override + public void addMotherboard() { + computerParts.put("Motherboard", "Standard Motherboard"); + } + + @Override + public void setupMotherboard() { + motherboardSetupStatus.add("Screwing the standard motherboard to the case."); + motherboardSetupStatus.add("Pluging in the power supply connectors."); + motherboardSetupStatus.forEach(step -> System.out.println(step)); + } + + @Override + public void addProcessor() { + computerParts.put("Processor", "Standard Processor"); + } +} diff --git a/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/templatemethod/test/TemplateMethodPatternTest.java b/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/templatemethod/test/TemplateMethodPatternTest.java new file mode 100644 index 0000000000..679559af9f --- /dev/null +++ b/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/templatemethod/test/TemplateMethodPatternTest.java @@ -0,0 +1,87 @@ +package com.baeldung.pattern.templatemethod.test; + +import com.baeldung.pattern.templatemethod.model.Computer; +import com.baeldung.pattern.templatemethod.model.HighEndComputerBuilder; +import com.baeldung.pattern.templatemethod.model.StandardComputerBuilder; +import org.junit.Assert; +import static org.junit.Assert.assertEquals; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.assertThat; + +public class TemplateMethodPatternTest { + + private static StandardComputerBuilder standardComputerBuilder; + private static HighEndComputerBuilder highEndComputerBuilder; + + @BeforeClass + public static void setUpStandardComputerBuilderInstance() { + standardComputerBuilder = new StandardComputerBuilder(); + } + + @BeforeClass + public static void setUpHighEndComputerBuilderInstance() { + highEndComputerBuilder = new HighEndComputerBuilder(); + } + + @Test + public void givenStandardMotherBoard_whenAddingMotherBoard_thenEqualAssertion() { + standardComputerBuilder.addMotherboard(); + assertEquals("Standard Motherboard", standardComputerBuilder.getComputerParts().get("Motherboard")); + } + + @Test + public void givenStandardMotherboard_whenSetup_thenTwoEqualAssertions() { + standardComputerBuilder.setupMotherboard(); + assertEquals("Screwing the standard motherboard to the case.", standardComputerBuilder.getMotherboardSetupStatus().get(0)); + assertEquals("Pluging in the power supply connectors.", standardComputerBuilder.getMotherboardSetupStatus().get(1)); + } + + @Test + public void givenStandardProcessor_whenAddingProcessor_thenEqualAssertion() { + standardComputerBuilder.addProcessor(); + assertEquals("Standard Processor", standardComputerBuilder.getComputerParts().get("Processor")); + } + + @Test + public void givenAllStandardParts_whenBuildingComputer_thenTwoParts() { + standardComputerBuilder.buildComputer(); + assertEquals(2, standardComputerBuilder.getComputerParts().size()); + } + + @Test + public void givenAllStandardParts_whenComputerisBuilt_thenComputerInstance() { + assertThat(standardComputerBuilder.buildComputer(), instanceOf(Computer.class)); + } + + @Test + public void givenHighEnddMotherBoard_whenAddingMotherBoard_thenEqualAssertion() { + highEndComputerBuilder.addMotherboard(); + Assert.assertEquals("High-end Motherboard", highEndComputerBuilder.getComputerParts().get("Motherboard")); + } + + @Test + public void givenHighEnddMotheroboard_whenSetup_thenTwoEqualAssertions() { + highEndComputerBuilder.setupMotherboard(); + assertEquals("Screwing the high-end motherboard to the case.", highEndComputerBuilder.getMotherboardSetupStatus().get(0)); + assertEquals("Pluging in the power supply connectors.", highEndComputerBuilder.getMotherboardSetupStatus().get(1)); + } + + @Test + public void givenHightEndProcessor_whenAddingProcessor_thenEqualAssertion() { + highEndComputerBuilder.addProcessor(); + assertEquals("High-end Processor", highEndComputerBuilder.getComputerParts().get("Processor")); + } + + @Test + public void givenAllHighEnddParts_whenBuildingComputer_thenTwoParts() { + highEndComputerBuilder.buildComputer(); + assertEquals(2, highEndComputerBuilder.getComputerParts().size()); + } + + @Test + public void givenAllHighEndParts_whenComputerisBuilt_thenComputerInstance() { + assertThat(standardComputerBuilder.buildComputer(), instanceOf(Computer.class)); + } +} diff --git a/patterns/pom.xml b/patterns/pom.xml index c40d7c58b7..1462952e37 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -9,6 +9,7 @@ front-controller intercepting-filter + behavioral-patterns @@ -51,4 +52,4 @@ 3.0.0 9.4.0.v20161208 - + \ No newline at end of file diff --git a/persistence-modules/README.md b/persistence-modules/README.md new file mode 100644 index 0000000000..6c2b1d2ca9 --- /dev/null +++ b/persistence-modules/README.md @@ -0,0 +1,3 @@ + +## Persistence Modules + diff --git a/java-cassandra/README.md b/persistence-modules/java-cassandra/README.md similarity index 100% rename from java-cassandra/README.md rename to persistence-modules/java-cassandra/README.md diff --git a/java-cassandra/pom.xml b/persistence-modules/java-cassandra/pom.xml similarity index 98% rename from java-cassandra/pom.xml rename to persistence-modules/java-cassandra/pom.xml index 12df920e7d..81e072c3a7 100644 --- a/java-cassandra/pom.xml +++ b/persistence-modules/java-cassandra/pom.xml @@ -11,6 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraClient.java b/persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraClient.java similarity index 100% rename from java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraClient.java rename to persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraClient.java diff --git a/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraConnector.java b/persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraConnector.java similarity index 100% rename from java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraConnector.java rename to persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/CassandraConnector.java diff --git a/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/domain/Book.java b/persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/domain/Book.java similarity index 100% rename from java-cassandra/src/main/java/com/baeldung/cassandra/java/client/domain/Book.java rename to persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/domain/Book.java diff --git a/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/BookRepository.java b/persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/BookRepository.java similarity index 100% rename from java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/BookRepository.java rename to persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/BookRepository.java diff --git a/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepository.java b/persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepository.java similarity index 100% rename from java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepository.java rename to persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepository.java diff --git a/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryIntegrationTest.java b/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryIntegrationTest.java similarity index 100% rename from java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryIntegrationTest.java rename to persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryIntegrationTest.java diff --git a/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryIntegrationTest.java b/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryIntegrationTest.java similarity index 100% rename from java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryIntegrationTest.java rename to persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryIntegrationTest.java diff --git a/java-mongodb/.gitignore b/persistence-modules/java-mongodb/.gitignore similarity index 100% rename from java-mongodb/.gitignore rename to persistence-modules/java-mongodb/.gitignore diff --git a/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md similarity index 100% rename from java-mongodb/README.md rename to persistence-modules/java-mongodb/README.md diff --git a/java-mongodb/pom.xml b/persistence-modules/java-mongodb/pom.xml similarity index 97% rename from java-mongodb/pom.xml rename to persistence-modules/java-mongodb/pom.xml index 304d961b0a..9784b2c5a8 100644 --- a/java-mongodb/pom.xml +++ b/persistence-modules/java-mongodb/pom.xml @@ -11,6 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/java-mongodb/src/main/java/com/baeldung/MongoExample.java b/persistence-modules/java-mongodb/src/main/java/com/baeldung/MongoExample.java similarity index 100% rename from java-mongodb/src/main/java/com/baeldung/MongoExample.java rename to persistence-modules/java-mongodb/src/main/java/com/baeldung/MongoExample.java diff --git a/java-mongodb/src/test/java/com/baeldung/AppIntegrationTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/AppIntegrationTest.java similarity index 100% rename from java-mongodb/src/test/java/com/baeldung/AppIntegrationTest.java rename to persistence-modules/java-mongodb/src/test/java/com/baeldung/AppIntegrationTest.java diff --git a/liquibase/README.md b/persistence-modules/liquibase/README.md similarity index 100% rename from liquibase/README.md rename to persistence-modules/liquibase/README.md diff --git a/liquibase/pom.xml b/persistence-modules/liquibase/pom.xml similarity index 96% rename from liquibase/pom.xml rename to persistence-modules/liquibase/pom.xml index d26acc8c98..a574ba497c 100644 --- a/liquibase/pom.xml +++ b/persistence-modules/liquibase/pom.xml @@ -6,6 +6,7 @@ parent-modules com.baeldung 1.0.0-SNAPSHOT + ../../ 4.0.0 diff --git a/liquibase/src/main/resources/liquibase/db-changelog.xml b/persistence-modules/liquibase/src/main/resources/liquibase/db-changelog.xml similarity index 100% rename from liquibase/src/main/resources/liquibase/db-changelog.xml rename to persistence-modules/liquibase/src/main/resources/liquibase/db-changelog.xml diff --git a/liquibase/src/main/resources/liquibase/liquibase.properties b/persistence-modules/liquibase/src/main/resources/liquibase/liquibase.properties similarity index 100% rename from liquibase/src/main/resources/liquibase/liquibase.properties rename to persistence-modules/liquibase/src/main/resources/liquibase/liquibase.properties diff --git a/querydsl/README.md b/persistence-modules/querydsl/README.md similarity index 100% rename from querydsl/README.md rename to persistence-modules/querydsl/README.md diff --git a/querydsl/pom.xml b/persistence-modules/querydsl/pom.xml similarity index 99% rename from querydsl/pom.xml rename to persistence-modules/querydsl/pom.xml index 6c968f01e4..c2943875f1 100644 --- a/querydsl/pom.xml +++ b/persistence-modules/querydsl/pom.xml @@ -15,6 +15,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/querydsl/src/main/java/org/baeldung/dao/PersonDao.java b/persistence-modules/querydsl/src/main/java/org/baeldung/dao/PersonDao.java similarity index 100% rename from querydsl/src/main/java/org/baeldung/dao/PersonDao.java rename to persistence-modules/querydsl/src/main/java/org/baeldung/dao/PersonDao.java diff --git a/querydsl/src/main/java/org/baeldung/dao/PersonDaoImpl.java b/persistence-modules/querydsl/src/main/java/org/baeldung/dao/PersonDaoImpl.java similarity index 100% rename from querydsl/src/main/java/org/baeldung/dao/PersonDaoImpl.java rename to persistence-modules/querydsl/src/main/java/org/baeldung/dao/PersonDaoImpl.java diff --git a/querydsl/src/main/java/org/baeldung/entity/Person.java b/persistence-modules/querydsl/src/main/java/org/baeldung/entity/Person.java similarity index 100% rename from querydsl/src/main/java/org/baeldung/entity/Person.java rename to persistence-modules/querydsl/src/main/java/org/baeldung/entity/Person.java diff --git a/querydsl/src/main/java/org/baeldung/querydsl/intro/entities/BlogPost.java b/persistence-modules/querydsl/src/main/java/org/baeldung/querydsl/intro/entities/BlogPost.java similarity index 100% rename from querydsl/src/main/java/org/baeldung/querydsl/intro/entities/BlogPost.java rename to persistence-modules/querydsl/src/main/java/org/baeldung/querydsl/intro/entities/BlogPost.java diff --git a/querydsl/src/main/java/org/baeldung/querydsl/intro/entities/User.java b/persistence-modules/querydsl/src/main/java/org/baeldung/querydsl/intro/entities/User.java similarity index 100% rename from querydsl/src/main/java/org/baeldung/querydsl/intro/entities/User.java rename to persistence-modules/querydsl/src/main/java/org/baeldung/querydsl/intro/entities/User.java diff --git a/querydsl/src/main/resources/META-INF/persistence.xml b/persistence-modules/querydsl/src/main/resources/META-INF/persistence.xml similarity index 100% rename from querydsl/src/main/resources/META-INF/persistence.xml rename to persistence-modules/querydsl/src/main/resources/META-INF/persistence.xml diff --git a/querydsl/src/main/resources/logback.xml b/persistence-modules/querydsl/src/main/resources/logback.xml similarity index 100% rename from querydsl/src/main/resources/logback.xml rename to persistence-modules/querydsl/src/main/resources/logback.xml diff --git a/querydsl/src/test/java/org/baeldung/dao/PersonDaoIntegrationTest.java b/persistence-modules/querydsl/src/test/java/org/baeldung/dao/PersonDaoIntegrationTest.java similarity index 100% rename from querydsl/src/test/java/org/baeldung/dao/PersonDaoIntegrationTest.java rename to persistence-modules/querydsl/src/test/java/org/baeldung/dao/PersonDaoIntegrationTest.java diff --git a/querydsl/src/test/java/org/baeldung/querydsl/intro/QueryDSLIntegrationTest.java b/persistence-modules/querydsl/src/test/java/org/baeldung/querydsl/intro/QueryDSLIntegrationTest.java similarity index 100% rename from querydsl/src/test/java/org/baeldung/querydsl/intro/QueryDSLIntegrationTest.java rename to persistence-modules/querydsl/src/test/java/org/baeldung/querydsl/intro/QueryDSLIntegrationTest.java diff --git a/querydsl/src/test/resources/db.properties b/persistence-modules/querydsl/src/test/resources/db.properties similarity index 100% rename from querydsl/src/test/resources/db.properties rename to persistence-modules/querydsl/src/test/resources/db.properties diff --git a/querydsl/src/test/resources/test-context.xml b/persistence-modules/querydsl/src/test/resources/test-context.xml similarity index 100% rename from querydsl/src/test/resources/test-context.xml rename to persistence-modules/querydsl/src/test/resources/test-context.xml diff --git a/querydsl/src/test/resources/test-db.xml b/persistence-modules/querydsl/src/test/resources/test-db.xml similarity index 100% rename from querydsl/src/test/resources/test-db.xml rename to persistence-modules/querydsl/src/test/resources/test-db.xml diff --git a/redis/README.md b/persistence-modules/redis/README.md similarity index 100% rename from redis/README.md rename to persistence-modules/redis/README.md diff --git a/redis/pom.xml b/persistence-modules/redis/pom.xml similarity index 96% rename from redis/pom.xml rename to persistence-modules/redis/pom.xml index db454188a7..4321b491eb 100644 --- a/redis/pom.xml +++ b/persistence-modules/redis/pom.xml @@ -15,6 +15,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/redis/src/main/java/com/baeldung/CustomMessage.java b/persistence-modules/redis/src/main/java/com/baeldung/CustomMessage.java similarity index 100% rename from redis/src/main/java/com/baeldung/CustomMessage.java rename to persistence-modules/redis/src/main/java/com/baeldung/CustomMessage.java diff --git a/redis/src/main/java/com/baeldung/Ledger.java b/persistence-modules/redis/src/main/java/com/baeldung/Ledger.java similarity index 100% rename from redis/src/main/java/com/baeldung/Ledger.java rename to persistence-modules/redis/src/main/java/com/baeldung/Ledger.java diff --git a/redis/src/main/java/com/baeldung/LedgerLiveObject.java b/persistence-modules/redis/src/main/java/com/baeldung/LedgerLiveObject.java similarity index 100% rename from redis/src/main/java/com/baeldung/LedgerLiveObject.java rename to persistence-modules/redis/src/main/java/com/baeldung/LedgerLiveObject.java diff --git a/redis/src/main/java/com/baeldung/LedgerServiceImpl.java b/persistence-modules/redis/src/main/java/com/baeldung/LedgerServiceImpl.java similarity index 100% rename from redis/src/main/java/com/baeldung/LedgerServiceImpl.java rename to persistence-modules/redis/src/main/java/com/baeldung/LedgerServiceImpl.java diff --git a/redis/src/main/java/com/baeldung/LedgerServiceInterface.java b/persistence-modules/redis/src/main/java/com/baeldung/LedgerServiceInterface.java similarity index 100% rename from redis/src/main/java/com/baeldung/LedgerServiceInterface.java rename to persistence-modules/redis/src/main/java/com/baeldung/LedgerServiceInterface.java diff --git a/redis/src/main/resources/singleNodeConfig.json b/persistence-modules/redis/src/main/resources/singleNodeConfig.json similarity index 100% rename from redis/src/main/resources/singleNodeConfig.json rename to persistence-modules/redis/src/main/resources/singleNodeConfig.json diff --git a/redis/src/main/resources/singleNodeConfig.yaml b/persistence-modules/redis/src/main/resources/singleNodeConfig.yaml similarity index 100% rename from redis/src/main/resources/singleNodeConfig.yaml rename to persistence-modules/redis/src/main/resources/singleNodeConfig.yaml diff --git a/redis/src/test/java/com/baeldung/JedisIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/JedisIntegrationTest.java similarity index 100% rename from redis/src/test/java/com/baeldung/JedisIntegrationTest.java rename to persistence-modules/redis/src/test/java/com/baeldung/JedisIntegrationTest.java diff --git a/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java similarity index 100% rename from redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java rename to persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java diff --git a/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java similarity index 100% rename from redis/src/test/java/com/baeldung/RedissonIntegrationTest.java rename to persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java diff --git a/solr/README.md b/persistence-modules/solr/README.md similarity index 100% rename from solr/README.md rename to persistence-modules/solr/README.md diff --git a/solr/pom.xml b/persistence-modules/solr/pom.xml similarity index 93% rename from solr/pom.xml rename to persistence-modules/solr/pom.xml index 1b26a21edc..966bd8755b 100644 --- a/solr/pom.xml +++ b/persistence-modules/solr/pom.xml @@ -12,6 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/solr/src/main/java/com/baeldung/solr/fulltext/search/model/Item.java b/persistence-modules/solr/src/main/java/com/baeldung/solr/fulltext/search/model/Item.java similarity index 100% rename from solr/src/main/java/com/baeldung/solr/fulltext/search/model/Item.java rename to persistence-modules/solr/src/main/java/com/baeldung/solr/fulltext/search/model/Item.java diff --git a/solr/src/main/java/com/baeldung/solr/fulltext/search/service/ItemSearchService.java b/persistence-modules/solr/src/main/java/com/baeldung/solr/fulltext/search/service/ItemSearchService.java similarity index 100% rename from solr/src/main/java/com/baeldung/solr/fulltext/search/service/ItemSearchService.java rename to persistence-modules/solr/src/main/java/com/baeldung/solr/fulltext/search/service/ItemSearchService.java diff --git a/solr/src/main/java/com/baeldung/solr/fulltext/search/service/ItemSearchServiceImpl.java b/persistence-modules/solr/src/main/java/com/baeldung/solr/fulltext/search/service/ItemSearchServiceImpl.java similarity index 100% rename from solr/src/main/java/com/baeldung/solr/fulltext/search/service/ItemSearchServiceImpl.java rename to persistence-modules/solr/src/main/java/com/baeldung/solr/fulltext/search/service/ItemSearchServiceImpl.java diff --git a/solr/src/test/java/com/baeldung/solr/fulltext/search/service/ItemSearchServiceLiveTest.java b/persistence-modules/solr/src/test/java/com/baeldung/solr/fulltext/search/service/ItemSearchServiceLiveTest.java similarity index 100% rename from solr/src/test/java/com/baeldung/solr/fulltext/search/service/ItemSearchServiceLiveTest.java rename to persistence-modules/solr/src/test/java/com/baeldung/solr/fulltext/search/service/ItemSearchServiceLiveTest.java diff --git a/spring-data-cassandra/README.md b/persistence-modules/spring-data-cassandra/README.md similarity index 100% rename from spring-data-cassandra/README.md rename to persistence-modules/spring-data-cassandra/README.md diff --git a/spring-data-cassandra/pom.xml b/persistence-modules/spring-data-cassandra/pom.xml similarity index 98% rename from spring-data-cassandra/pom.xml rename to persistence-modules/spring-data-cassandra/pom.xml index fbc2071134..1358210a45 100644 --- a/spring-data-cassandra/pom.xml +++ b/persistence-modules/spring-data-cassandra/pom.xml @@ -13,6 +13,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/config/CassandraConfig.java b/persistence-modules/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/config/CassandraConfig.java similarity index 100% rename from spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/config/CassandraConfig.java rename to persistence-modules/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/config/CassandraConfig.java diff --git a/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/model/Book.java b/persistence-modules/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/model/Book.java similarity index 100% rename from spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/model/Book.java rename to persistence-modules/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/model/Book.java diff --git a/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/repository/BookRepository.java b/persistence-modules/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/repository/BookRepository.java similarity index 100% rename from spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/repository/BookRepository.java rename to persistence-modules/spring-data-cassandra/src/main/java/org/baeldung/spring/data/cassandra/repository/BookRepository.java diff --git a/spring-data-cassandra/src/main/resources/cassandra.properties b/persistence-modules/spring-data-cassandra/src/main/resources/cassandra.properties similarity index 100% rename from spring-data-cassandra/src/main/resources/cassandra.properties rename to persistence-modules/spring-data-cassandra/src/main/resources/cassandra.properties diff --git a/rest-assured/src/test/resources/logback.xml b/persistence-modules/spring-data-cassandra/src/main/resources/logback.xml similarity index 100% rename from rest-assured/src/test/resources/logback.xml rename to persistence-modules/spring-data-cassandra/src/main/resources/logback.xml diff --git a/spring-data-cassandra/src/main/resources/test.png b/persistence-modules/spring-data-cassandra/src/main/resources/test.png similarity index 100% rename from spring-data-cassandra/src/main/resources/test.png rename to persistence-modules/spring-data-cassandra/src/main/resources/test.png diff --git a/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java b/persistence-modules/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java similarity index 100% rename from spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java rename to persistence-modules/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java diff --git a/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/CassandraTemplateIntegrationTest.java b/persistence-modules/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/CassandraTemplateIntegrationTest.java similarity index 100% rename from spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/CassandraTemplateIntegrationTest.java rename to persistence-modules/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/CassandraTemplateIntegrationTest.java diff --git a/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/CqlQueriesIntegrationTest.java b/persistence-modules/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/CqlQueriesIntegrationTest.java similarity index 100% rename from spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/CqlQueriesIntegrationTest.java rename to persistence-modules/spring-data-cassandra/src/test/java/org/baeldung/spring/data/cassandra/repository/CqlQueriesIntegrationTest.java diff --git a/spring-data-dynamodb/.gitignore b/persistence-modules/spring-data-dynamodb/.gitignore similarity index 100% rename from spring-data-dynamodb/.gitignore rename to persistence-modules/spring-data-dynamodb/.gitignore diff --git a/spring-data-dynamodb/README.MD b/persistence-modules/spring-data-dynamodb/README.MD similarity index 100% rename from spring-data-dynamodb/README.MD rename to persistence-modules/spring-data-dynamodb/README.MD diff --git a/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml similarity index 96% rename from spring-data-dynamodb/pom.xml rename to persistence-modules/spring-data-dynamodb/pom.xml index 11bbbdf40f..bf90779c29 100644 --- a/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -12,7 +12,7 @@ parent-boot-5 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../../parent-boot-5 diff --git a/spring-data-dynamodb/src/main/java/com/baeldung/Application.java b/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/Application.java similarity index 100% rename from spring-data-dynamodb/src/main/java/com/baeldung/Application.java rename to persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/Application.java diff --git a/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java b/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java similarity index 100% rename from spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java rename to persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/config/DynamoDBConfig.java diff --git a/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/model/ProductInfo.java b/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/model/ProductInfo.java similarity index 100% rename from spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/model/ProductInfo.java rename to persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/model/ProductInfo.java diff --git a/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/repositories/ProductInfoRepository.java b/persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/repositories/ProductInfoRepository.java similarity index 100% rename from spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/repositories/ProductInfoRepository.java rename to persistence-modules/spring-data-dynamodb/src/main/java/com/baeldung/spring/data/dynamodb/repositories/ProductInfoRepository.java diff --git a/spring-data-dynamodb/src/main/resources/application.properties b/persistence-modules/spring-data-dynamodb/src/main/resources/application.properties similarity index 100% rename from spring-data-dynamodb/src/main/resources/application.properties rename to persistence-modules/spring-data-dynamodb/src/main/resources/application.properties diff --git a/spring-data-dynamodb/src/main/resources/demo.properties b/persistence-modules/spring-data-dynamodb/src/main/resources/demo.properties similarity index 100% rename from spring-data-dynamodb/src/main/resources/demo.properties rename to persistence-modules/spring-data-dynamodb/src/main/resources/demo.properties diff --git a/rest-testing/src/main/resources/logback.xml b/persistence-modules/spring-data-dynamodb/src/main/resources/logback.xml similarity index 100% rename from rest-testing/src/main/resources/logback.xml rename to persistence-modules/spring-data-dynamodb/src/main/resources/logback.xml diff --git a/spring-data-dynamodb/src/main/resources/templates/index.html b/persistence-modules/spring-data-dynamodb/src/main/resources/templates/index.html similarity index 100% rename from spring-data-dynamodb/src/main/resources/templates/index.html rename to persistence-modules/spring-data-dynamodb/src/main/resources/templates/index.html diff --git a/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java similarity index 100% rename from spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java rename to persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/spring/data/dynamodb/repository/ProductInfoRepositoryIntegrationTest.java diff --git a/spring-data-dynamodb/src/test/resources/application.properties b/persistence-modules/spring-data-dynamodb/src/test/resources/application.properties similarity index 100% rename from spring-data-dynamodb/src/test/resources/application.properties rename to persistence-modules/spring-data-dynamodb/src/test/resources/application.properties diff --git a/spring-data-dynamodb/src/test/resources/exception-hibernate.properties b/persistence-modules/spring-data-dynamodb/src/test/resources/exception-hibernate.properties similarity index 100% rename from spring-data-dynamodb/src/test/resources/exception-hibernate.properties rename to persistence-modules/spring-data-dynamodb/src/test/resources/exception-hibernate.properties diff --git a/spring-data-dynamodb/src/test/resources/exception.properties b/persistence-modules/spring-data-dynamodb/src/test/resources/exception.properties similarity index 100% rename from spring-data-dynamodb/src/test/resources/exception.properties rename to persistence-modules/spring-data-dynamodb/src/test/resources/exception.properties diff --git a/spring-data-gemfire/README.md b/persistence-modules/spring-data-gemfire/README.md similarity index 100% rename from spring-data-gemfire/README.md rename to persistence-modules/spring-data-gemfire/README.md diff --git a/spring-data-gemfire/pom.xml b/persistence-modules/spring-data-gemfire/pom.xml similarity index 97% rename from spring-data-gemfire/pom.xml rename to persistence-modules/spring-data-gemfire/pom.xml index ae7612d719..3f7fcd03e5 100644 --- a/spring-data-gemfire/pom.xml +++ b/persistence-modules/spring-data-gemfire/pom.xml @@ -12,6 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionExecution.java b/persistence-modules/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionExecution.java similarity index 100% rename from spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionExecution.java rename to persistence-modules/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionExecution.java diff --git a/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionImpl.java b/persistence-modules/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionImpl.java similarity index 100% rename from spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionImpl.java rename to persistence-modules/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/FunctionImpl.java diff --git a/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/GemfireConfiguration.java b/persistence-modules/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/GemfireConfiguration.java similarity index 100% rename from spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/GemfireConfiguration.java rename to persistence-modules/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/function/GemfireConfiguration.java diff --git a/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/model/Employee.java b/persistence-modules/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/model/Employee.java similarity index 100% rename from spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/model/Employee.java rename to persistence-modules/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/model/Employee.java diff --git a/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepository.java b/persistence-modules/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepository.java similarity index 100% rename from spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepository.java rename to persistence-modules/spring-data-gemfire/src/main/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepository.java diff --git a/spring-data-gemfire/src/main/resources/application-context.xml b/persistence-modules/spring-data-gemfire/src/main/resources/application-context.xml similarity index 100% rename from spring-data-gemfire/src/main/resources/application-context.xml rename to persistence-modules/spring-data-gemfire/src/main/resources/application-context.xml diff --git a/spring-data-gemfire/src/test/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepositoryIntegrationTest.java b/persistence-modules/spring-data-gemfire/src/test/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepositoryIntegrationTest.java similarity index 100% rename from spring-data-gemfire/src/test/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepositoryIntegrationTest.java rename to persistence-modules/spring-data-gemfire/src/test/java/com/baeldung/spring/data/gemfire/repository/EmployeeRepositoryIntegrationTest.java diff --git a/spring-data-neo4j/README.md b/persistence-modules/spring-data-neo4j/README.md similarity index 100% rename from spring-data-neo4j/README.md rename to persistence-modules/spring-data-neo4j/README.md diff --git a/spring-data-neo4j/pom.xml b/persistence-modules/spring-data-neo4j/pom.xml similarity index 99% rename from spring-data-neo4j/pom.xml rename to persistence-modules/spring-data-neo4j/pom.xml index e01e7d7294..bdd51e9659 100644 --- a/spring-data-neo4j/pom.xml +++ b/persistence-modules/spring-data-neo4j/pom.xml @@ -10,6 +10,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java similarity index 100% rename from spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jConfiguration.java diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java similarity index 100% rename from spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/config/MovieDatabaseNeo4jTestConfiguration.java diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java similarity index 100% rename from spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Car.java diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Company.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Company.java similarity index 100% rename from spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Company.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Company.java diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Movie.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Movie.java similarity index 100% rename from spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Movie.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Movie.java diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Person.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Person.java similarity index 100% rename from spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Person.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Person.java diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Role.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Role.java similarity index 100% rename from spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Role.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/domain/Role.java diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java similarity index 100% rename from spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/MovieRepository.java diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java similarity index 100% rename from spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/repostory/PersonRepository.java diff --git a/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java b/persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java similarity index 100% rename from spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java rename to persistence-modules/spring-data-neo4j/src/main/java/com/baeldung/spring/data/neo4j/services/MovieService.java diff --git a/spring-data-cassandra/src/main/resources/logback.xml b/persistence-modules/spring-data-neo4j/src/main/resources/logback.xml similarity index 100% rename from spring-data-cassandra/src/main/resources/logback.xml rename to persistence-modules/spring-data-neo4j/src/main/resources/logback.xml diff --git a/spring-data-neo4j/src/main/resources/test.png b/persistence-modules/spring-data-neo4j/src/main/resources/test.png similarity index 100% rename from spring-data-neo4j/src/main/resources/test.png rename to persistence-modules/spring-data-neo4j/src/main/resources/test.png diff --git a/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerLiveTest.java b/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerLiveTest.java similarity index 100% rename from spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerLiveTest.java rename to persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4JServerLiveTest.java diff --git a/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java b/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java similarity index 100% rename from spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java rename to persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jLiveTest.java diff --git a/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java b/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java similarity index 100% rename from spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java rename to persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/neo4j/Neo4jOgmLiveTest.java diff --git a/spring-data-neo4j/src/test/java/com/baeldung/spring/data/neo4j/MovieRepositoryIntegrationTest.java b/persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/spring/data/neo4j/MovieRepositoryIntegrationTest.java similarity index 100% rename from spring-data-neo4j/src/test/java/com/baeldung/spring/data/neo4j/MovieRepositoryIntegrationTest.java rename to persistence-modules/spring-data-neo4j/src/test/java/com/baeldung/spring/data/neo4j/MovieRepositoryIntegrationTest.java diff --git a/spring-data-dynamodb/src/main/resources/logback.xml b/persistence-modules/spring-data-neo4j/src/test/resources/logback.xml similarity index 100% rename from spring-data-dynamodb/src/main/resources/logback.xml rename to persistence-modules/spring-data-neo4j/src/test/resources/logback.xml diff --git a/spring-data-redis/README.md b/persistence-modules/spring-data-redis/README.md similarity index 100% rename from spring-data-redis/README.md rename to persistence-modules/spring-data-redis/README.md diff --git a/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml similarity index 98% rename from spring-data-redis/pom.xml rename to persistence-modules/spring-data-redis/pom.xml index d2835595da..6cb49f11cf 100644 --- a/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -11,6 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java similarity index 100% rename from spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java rename to persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/config/RedisConfig.java diff --git a/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/model/Student.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/model/Student.java similarity index 100% rename from spring-data-redis/src/main/java/com/baeldung/spring/data/redis/model/Student.java rename to persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/model/Student.java diff --git a/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/MessagePublisher.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/MessagePublisher.java similarity index 100% rename from spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/MessagePublisher.java rename to persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/MessagePublisher.java diff --git a/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/RedisMessagePublisher.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/RedisMessagePublisher.java similarity index 100% rename from spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/RedisMessagePublisher.java rename to persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/RedisMessagePublisher.java diff --git a/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/RedisMessageSubscriber.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/RedisMessageSubscriber.java similarity index 100% rename from spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/RedisMessageSubscriber.java rename to persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/queue/RedisMessageSubscriber.java diff --git a/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepository.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepository.java similarity index 100% rename from spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepository.java rename to persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepository.java diff --git a/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepositoryImpl.java b/persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepositoryImpl.java similarity index 100% rename from spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepositoryImpl.java rename to persistence-modules/spring-data-redis/src/main/java/com/baeldung/spring/data/redis/repo/StudentRepositoryImpl.java diff --git a/spring-data-neo4j/src/main/resources/logback.xml b/persistence-modules/spring-data-redis/src/main/resources/logback.xml similarity index 100% rename from spring-data-neo4j/src/main/resources/logback.xml rename to persistence-modules/spring-data-redis/src/main/resources/logback.xml diff --git a/spring-data-redis/src/main/resources/test.png b/persistence-modules/spring-data-redis/src/main/resources/test.png similarity index 100% rename from spring-data-redis/src/main/resources/test.png rename to persistence-modules/spring-data-redis/src/main/resources/test.png diff --git a/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java similarity index 100% rename from spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java rename to persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java diff --git a/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java similarity index 100% rename from spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java rename to persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java diff --git a/spring-data-solr/README.md b/persistence-modules/spring-data-solr/README.md similarity index 100% rename from spring-data-solr/README.md rename to persistence-modules/spring-data-solr/README.md diff --git a/spring-data-solr/pom.xml b/persistence-modules/spring-data-solr/pom.xml similarity index 96% rename from spring-data-solr/pom.xml rename to persistence-modules/spring-data-solr/pom.xml index 48ddaa7085..e24d8314ba 100644 --- a/spring-data-solr/pom.xml +++ b/persistence-modules/spring-data-solr/pom.xml @@ -12,6 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java b/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java similarity index 100% rename from spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java rename to persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/config/SolrConfig.java diff --git a/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/model/Product.java b/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/model/Product.java similarity index 100% rename from spring-data-solr/src/main/java/com/baeldung/spring/data/solr/model/Product.java rename to persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/model/Product.java diff --git a/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java b/persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java similarity index 100% rename from spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java rename to persistence-modules/spring-data-solr/src/main/java/com/baeldung/spring/data/solr/repository/ProductRepository.java diff --git a/spring-data-solr/src/main/resources/solr-named-queries.properties b/persistence-modules/spring-data-solr/src/main/resources/solr-named-queries.properties similarity index 100% rename from spring-data-solr/src/main/resources/solr-named-queries.properties rename to persistence-modules/spring-data-solr/src/main/resources/solr-named-queries.properties diff --git a/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryIntegrationTest.java b/persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryIntegrationTest.java similarity index 100% rename from spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryIntegrationTest.java rename to persistence-modules/spring-data-solr/src/test/java/com/baeldung/spring/data/solr/repo/ProductRepositoryIntegrationTest.java diff --git a/spring-hibernate3/src/test/resources/.gitignore b/persistence-modules/spring-hibernate-3/.gitignore similarity index 100% rename from spring-hibernate3/src/test/resources/.gitignore rename to persistence-modules/spring-hibernate-3/.gitignore diff --git a/spring-hibernate3/README.md b/persistence-modules/spring-hibernate-3/README.md similarity index 100% rename from spring-hibernate3/README.md rename to persistence-modules/spring-hibernate-3/README.md diff --git a/spring-hibernate3/pom.xml b/persistence-modules/spring-hibernate-3/pom.xml similarity index 95% rename from spring-hibernate3/pom.xml rename to persistence-modules/spring-hibernate-3/pom.xml index d7607cac0a..f1873a84d3 100644 --- a/spring-hibernate3/pom.xml +++ b/persistence-modules/spring-hibernate-3/pom.xml @@ -2,15 +2,16 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung - spring-hibernate3 + spring-hibernate-3 0.1-SNAPSHOT - spring-hibernate3 + spring-hibernate-3 com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ @@ -87,7 +88,7 @@ - spring-hibernate3 + spring-hibernate-3 src/main/resources @@ -141,7 +142,7 @@ 3.6.10.Final 5.1.40 - 7.0.73 + 8.5.8 1.4.193 @@ -162,4 +163,4 @@ - \ No newline at end of file + diff --git a/spring-hibernate3/src/main/java/org/baeldung/persistence/dao/AbstractHibernateDao.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/AbstractHibernateDao.java similarity index 100% rename from spring-hibernate3/src/main/java/org/baeldung/persistence/dao/AbstractHibernateDao.java rename to persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/AbstractHibernateDao.java diff --git a/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/EventDao.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/EventDao.java new file mode 100644 index 0000000000..74da643f35 --- /dev/null +++ b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/EventDao.java @@ -0,0 +1,18 @@ +package org.baeldung.persistence.dao; + + +import org.baeldung.persistence.model.Event; +import org.springframework.stereotype.Repository; + +@Repository +public class EventDao extends AbstractHibernateDao implements IEventDao { + + public EventDao() { + super(); + + setClazz(Event.class); + } + + // API + +} diff --git a/spring-hibernate3/src/main/java/org/baeldung/persistence/dao/FooDao.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/FooDao.java similarity index 100% rename from spring-hibernate3/src/main/java/org/baeldung/persistence/dao/FooDao.java rename to persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/FooDao.java diff --git a/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/IEventDao.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/IEventDao.java new file mode 100644 index 0000000000..f7be705905 --- /dev/null +++ b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/IEventDao.java @@ -0,0 +1,9 @@ +package org.baeldung.persistence.dao; + +import org.baeldung.persistence.model.Event; + + + +public interface IEventDao extends IOperations { + // +} diff --git a/spring-hibernate3/src/main/java/org/baeldung/persistence/dao/IFooDao.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/IFooDao.java similarity index 100% rename from spring-hibernate3/src/main/java/org/baeldung/persistence/dao/IFooDao.java rename to persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/IFooDao.java diff --git a/spring-hibernate3/src/main/java/org/baeldung/persistence/dao/IOperations.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/IOperations.java similarity index 100% rename from spring-hibernate3/src/main/java/org/baeldung/persistence/dao/IOperations.java rename to persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/dao/IOperations.java diff --git a/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/model/Event.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/model/Event.java new file mode 100644 index 0000000000..1d659ed75c --- /dev/null +++ b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/model/Event.java @@ -0,0 +1,45 @@ +package org.baeldung.persistence.model; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "EVENTS") +public class Event implements Serializable { + + @Id + @GeneratedValue + private Long id; + + private String description; + + public Event() { + } + + + public Event(String description) { + this.description = description; + } + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + } \ No newline at end of file diff --git a/spring-hibernate3/src/main/java/org/baeldung/persistence/model/Foo.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/model/Foo.java similarity index 100% rename from spring-hibernate3/src/main/java/org/baeldung/persistence/model/Foo.java rename to persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/model/Foo.java diff --git a/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/service/EventService.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/service/EventService.java new file mode 100644 index 0000000000..6171751cc5 --- /dev/null +++ b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/service/EventService.java @@ -0,0 +1,27 @@ +package org.baeldung.persistence.service; + + +import org.baeldung.persistence.dao.IEventDao; +import org.baeldung.persistence.model.Event; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class EventService { + + @Autowired + private IEventDao dao; + + public EventService() { + super(); + } + + // API + + public void create(final Event entity) { + dao.create(entity); + } + +} diff --git a/spring-hibernate3/src/main/java/org/baeldung/persistence/service/FooService.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/service/FooService.java similarity index 100% rename from spring-hibernate3/src/main/java/org/baeldung/persistence/service/FooService.java rename to persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/persistence/service/FooService.java diff --git a/spring-hibernate3/src/main/java/org/baeldung/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/spring/PersistenceConfig.java similarity index 98% rename from spring-hibernate3/src/main/java/org/baeldung/spring/PersistenceConfig.java rename to persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/spring/PersistenceConfig.java index fea76dfc70..03b9bfac33 100644 --- a/spring-hibernate3/src/main/java/org/baeldung/spring/PersistenceConfig.java +++ b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/spring/PersistenceConfig.java @@ -4,7 +4,7 @@ import java.util.Properties; import javax.sql.DataSource; -import org.apache.tomcat.dbcp.dbcp.BasicDataSource; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -75,4 +75,4 @@ public class PersistenceConfig { return hibernateProperties; } -} \ No newline at end of file +} diff --git a/spring-hibernate3/src/main/java/org/baeldung/spring/PersistenceXmlConfig.java b/persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/spring/PersistenceXmlConfig.java similarity index 100% rename from spring-hibernate3/src/main/java/org/baeldung/spring/PersistenceXmlConfig.java rename to persistence-modules/spring-hibernate-3/src/main/java/org/baeldung/spring/PersistenceXmlConfig.java diff --git a/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemo.cfg.xml b/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemo.cfg.xml new file mode 100644 index 0000000000..8a710cc559 --- /dev/null +++ b/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemo.cfg.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml b/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml new file mode 100644 index 0000000000..09314c67b1 --- /dev/null +++ b/persistence-modules/spring-hibernate-3/src/main/resources/exceptionDemoPersistenceConfig.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + classpath:exceptionDemo.cfg.xml + + + + ${hibernate.dialect} + true + create + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-data-neo4j/src/test/resources/logback.xml b/persistence-modules/spring-hibernate-3/src/main/resources/logback.xml similarity index 100% rename from spring-data-neo4j/src/test/resources/logback.xml rename to persistence-modules/spring-hibernate-3/src/main/resources/logback.xml diff --git a/spring-hibernate3/src/main/resources/persistence-h2.properties b/persistence-modules/spring-hibernate-3/src/main/resources/persistence-h2.properties similarity index 100% rename from spring-hibernate3/src/main/resources/persistence-h2.properties rename to persistence-modules/spring-hibernate-3/src/main/resources/persistence-h2.properties diff --git a/spring-hibernate3/src/main/resources/persistence-mysql.properties b/persistence-modules/spring-hibernate-3/src/main/resources/persistence-mysql.properties similarity index 100% rename from spring-hibernate3/src/main/resources/persistence-mysql.properties rename to persistence-modules/spring-hibernate-3/src/main/resources/persistence-mysql.properties diff --git a/spring-hibernate3/src/main/resources/persistenceConfig.xml b/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml similarity index 94% rename from spring-hibernate3/src/main/resources/persistenceConfig.xml rename to persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml index 347e85ee51..e7ef9ad765 100644 --- a/spring-hibernate3/src/main/resources/persistenceConfig.xml +++ b/persistence-modules/spring-hibernate-3/src/main/resources/persistenceConfig.xml @@ -18,7 +18,7 @@ - + @@ -31,4 +31,4 @@ - \ No newline at end of file + diff --git a/spring-hibernate3/src/main/webapp/WEB-INF/view/sample.jsp b/persistence-modules/spring-hibernate-3/src/main/webapp/WEB-INF/view/sample.jsp similarity index 100% rename from spring-hibernate3/src/main/webapp/WEB-INF/view/sample.jsp rename to persistence-modules/spring-hibernate-3/src/main/webapp/WEB-INF/view/sample.jsp diff --git a/spring-hibernate3/src/main/webapp/WEB-INF/web.xml b/persistence-modules/spring-hibernate-3/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from spring-hibernate3/src/main/webapp/WEB-INF/web.xml rename to persistence-modules/spring-hibernate-3/src/main/webapp/WEB-INF/web.xml diff --git a/spring-hibernate3/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java b/persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java similarity index 100% rename from spring-hibernate3/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java rename to persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java diff --git a/persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/persistence/service/NoHibernateSessBoundUsingAnnoSessionBeanMainIntegrationTest.java b/persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/persistence/service/NoHibernateSessBoundUsingAnnoSessionBeanMainIntegrationTest.java new file mode 100644 index 0000000000..2b29dcb7a9 --- /dev/null +++ b/persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/persistence/service/NoHibernateSessBoundUsingAnnoSessionBeanMainIntegrationTest.java @@ -0,0 +1,42 @@ +package org.baeldung.persistence.service; + +import org.baeldung.persistence.model.Event; +import org.baeldung.spring.PersistenceXmlConfig; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.orm.hibernate3.HibernateSystemException; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceXmlConfig.class }, loader = AnnotationConfigContextLoader.class) +public class NoHibernateSessBoundUsingAnnoSessionBeanMainIntegrationTest { + + @Autowired + EventService service; + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + @Test + public final void whenEntityIsCreated_thenNoExceptions() { + service.create(new Event("from Annotation Session Bean Factory")); + } + + @Test + @Ignore + public final void whenNoTransBoundToSession_thenException() { + expectedEx.expect(HibernateSystemException.class); + expectedEx.expectMessage("No Hibernate Session bound to thread, " + + "and configuration does not allow creation of " + + "non-transactional one here"); + service.create(new Event("from Annotation Session Bean Factory")); + } + +} diff --git a/persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/persistence/service/NoHibernateSessBoundUsingLocalSessionBeanMainIntegrationTest.java b/persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/persistence/service/NoHibernateSessBoundUsingLocalSessionBeanMainIntegrationTest.java new file mode 100644 index 0000000000..1bc6c07b18 --- /dev/null +++ b/persistence-modules/spring-hibernate-3/src/test/java/org/baeldung/persistence/service/NoHibernateSessBoundUsingLocalSessionBeanMainIntegrationTest.java @@ -0,0 +1,39 @@ +package org.baeldung.persistence.service; + +import org.baeldung.persistence.model.Event; +import org.hibernate.HibernateException; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.orm.hibernate3.HibernateSystemException; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { "classpath:exceptionDemoPersistenceConfig.xml" }) +public class NoHibernateSessBoundUsingLocalSessionBeanMainIntegrationTest { + + @Autowired + EventService service; + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + @Test + public final void whenEntityIsCreated_thenNoExceptions() { + service.create(new Event("from local session bean factory")); + } + + @Test + @Ignore + public final void whenNoTransBoundToSession_thenException() { + expectedEx.expect(HibernateException.class); + expectedEx.expectMessage("No Hibernate Session bound to thread, " + + "and configuration does not allow creation " + + "of non-transactional one here"); + service.create(new Event("from local session bean factory")); + } +} diff --git a/spring-hibernate5/.gitignore b/persistence-modules/spring-hibernate-3/src/test/resources/.gitignore similarity index 100% rename from spring-hibernate5/.gitignore rename to persistence-modules/spring-hibernate-3/src/test/resources/.gitignore diff --git a/spring-hibernate5/src/test/resources/.gitignore b/persistence-modules/spring-hibernate-5/.gitignore similarity index 100% rename from spring-hibernate5/src/test/resources/.gitignore rename to persistence-modules/spring-hibernate-5/.gitignore diff --git a/spring-hibernate5/README.md b/persistence-modules/spring-hibernate-5/README.md similarity index 54% rename from spring-hibernate5/README.md rename to persistence-modules/spring-hibernate-5/README.md index fd539fdcb6..01a1ad7121 100644 --- a/spring-hibernate5/README.md +++ b/persistence-modules/spring-hibernate-5/README.md @@ -1,3 +1,4 @@ ### Relevant articles - [Guide to @Immutable Annotation in Hibernate](http://www.baeldung.com/hibernate-immutable) +- [Hibernate Many to Many Annotation Tutorial](http://www.baeldung.com/hibernate-many-to-many) diff --git a/spring-hibernate5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml similarity index 94% rename from spring-hibernate5/pom.xml rename to persistence-modules/spring-hibernate-5/pom.xml index dac43c4dd3..23cf9a4d44 100644 --- a/spring-hibernate5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -2,15 +2,16 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung - spring-hibernate5 + spring-hibernate-5 0.1-SNAPSHOT - spring-hibernate5 + spring-hibernate-5 com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ @@ -56,6 +57,11 @@ jta ${jta.version} + + org.hibernate + hibernate-search-orm + ${hibernatesearch.version} + org.apache.tomcat @@ -136,7 +142,7 @@ - spring-hibernate5 + spring-hibernate-5 src/main/resources @@ -183,6 +189,7 @@ 5.2.10.Final + 5.8.2.Final 8.0.7-dmr 9.0.0.M26 1.1 diff --git a/spring-hibernate5/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java similarity index 71% rename from spring-hibernate5/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java index 2928ffe981..ec88d629a6 100644 --- a/spring-hibernate5/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/entities/Event.java @@ -2,15 +2,9 @@ package com.baeldung.hibernate.immutable.entities; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; -import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Immutable; -import javax.persistence.Column; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; +import javax.persistence.*; import java.util.Set; @Entity @@ -20,8 +14,6 @@ public class Event { @Id @Column(name = "event_id") - @GeneratedValue(generator = "increment") - @GenericGenerator(name = "increment", strategy = "increment") private Long id; @Column(name = "title") @@ -31,6 +23,14 @@ public class Event { @Immutable private Set guestList; + public Event() {} + + public Event(Long id, String title, Set guestList) { + this.id = id; + this.title = title; + this.guestList = guestList; + } + public Long getId() { return id; } diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java new file mode 100644 index 0000000000..33af9313ae --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/entities/EventGeneratedId.java @@ -0,0 +1,55 @@ +package com.baeldung.hibernate.immutable.entities; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Immutable; + +import javax.persistence.*; + +@Entity +@Immutable +@Table(name = "events_generated") +public class EventGeneratedId { + + @Id + @Column(name = "event_generated_id") + @GeneratedValue(generator = "increment") + @GenericGenerator(name = "increment", strategy = "increment") + private Long id; + + @Column(name = "name") + private String name; + @Column(name = "description") + private String description; + + public EventGeneratedId() { + } + + public EventGeneratedId(String name, String description) { + this.name = name; + this.description = description; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} \ No newline at end of file diff --git a/spring-hibernate5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java similarity index 89% rename from spring-hibernate5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java index e4a2319c37..722f0251d1 100644 --- a/spring-hibernate5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/immutable/util/HibernateUtil.java @@ -1,6 +1,7 @@ package com.baeldung.hibernate.immutable.util; import com.baeldung.hibernate.immutable.entities.Event; +import com.baeldung.hibernate.immutable.entities.EventGeneratedId; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; @@ -14,6 +15,7 @@ public class HibernateUtil { // Create a session factory from immutable.cfg.xml Configuration configuration = new Configuration(); configuration.addAnnotatedClass(Event.class); + configuration.addAnnotatedClass(EventGeneratedId.class); configuration.configure("immutable.cfg.xml"); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); return configuration.buildSessionFactory(serviceRegistry); diff --git a/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Employee.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/model/Project.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernate/manytomany/util/HibernateUtil.java diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java new file mode 100644 index 0000000000..6bbd2625fc --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java @@ -0,0 +1,76 @@ +package com.baeldung.hibernatesearch; + +import com.google.common.base.Preconditions; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; +import java.util.Properties; + +@EnableTransactionManagement +@Configuration +@PropertySource({ "classpath:persistence-h2.properties" }) +@EnableJpaRepositories(basePackages = { "com.baeldung.hibernatesearch" }) +@ComponentScan({ "com.baeldung.hibernatesearch" }) +public class HibernateSearchConfig { + + @Autowired + private Environment env; + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory() { + LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(dataSource()); + em.setPackagesToScan(new String[] { "com.baeldung.hibernatesearch.model" }); + + JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + em.setJpaVendorAdapter(vendorAdapter); + em.setJpaProperties(additionalProperties()); + + return em; + } + + @Bean + public DataSource dataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager transactionManager(EntityManagerFactory emf) { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(emf); + + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + Properties additionalProperties() { + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", Preconditions.checkNotNull(env.getProperty("hibernate.hbm2ddl.auto"))); + properties.setProperty("hibernate.dialect", Preconditions.checkNotNull(env.getProperty("hibernate.dialect"))); + return properties; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/ProductSearchDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/ProductSearchDao.java new file mode 100644 index 0000000000..210c1c58b3 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/ProductSearchDao.java @@ -0,0 +1,195 @@ +package com.baeldung.hibernatesearch; + +import com.baeldung.hibernatesearch.model.Product; +import org.apache.lucene.search.Query; +import org.hibernate.search.engine.ProjectionConstants; +import org.hibernate.search.jpa.FullTextEntityManager; +import org.hibernate.search.jpa.FullTextQuery; +import org.hibernate.search.jpa.Search; +import org.hibernate.search.query.dsl.QueryBuilder; +import org.springframework.stereotype.Repository; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.List; + +@Repository +public class ProductSearchDao { + + @PersistenceContext + private EntityManager entityManager; + + public List searchProductNameByKeywordQuery(String text) { + + Query keywordQuery = getQueryBuilder() + .keyword() + .onField("productName") + .matching(text) + .createQuery(); + + List results = getJpaQuery(keywordQuery).getResultList(); + + return results; + } + + public List searchProductNameByFuzzyQuery(String text) { + + Query fuzzyQuery = getQueryBuilder() + .keyword() + .fuzzy() + .withEditDistanceUpTo(2) + .withPrefixLength(0) + .onField("productName") + .matching(text) + .createQuery(); + + List results = getJpaQuery(fuzzyQuery).getResultList(); + + return results; + } + + public List searchProductNameByWildcardQuery(String text) { + + Query wildcardQuery = getQueryBuilder() + .keyword() + .wildcard() + .onField("productName") + .matching(text) + .createQuery(); + + List results = getJpaQuery(wildcardQuery).getResultList(); + + return results; + } + + public List searchProductDescriptionByPhraseQuery(String text) { + + Query phraseQuery = getQueryBuilder() + .phrase() + .withSlop(1) + .onField("description") + .sentence(text) + .createQuery(); + + List results = getJpaQuery(phraseQuery).getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionBySimpleQueryStringQuery(String text) { + + Query simpleQueryStringQuery = getQueryBuilder() + .simpleQueryString() + .onFields("productName", "description") + .matching(text) + .createQuery(); + + List results = getJpaQuery(simpleQueryStringQuery).getResultList(); + + return results; + } + + public List searchProductNameByRangeQuery(int low, int high) { + + Query rangeQuery = getQueryBuilder() + .range() + .onField("memory") + .from(low) + .to(high) + .createQuery(); + + List results = getJpaQuery(rangeQuery).getResultList(); + + return results; + } + + public List searchProductNameByMoreLikeThisQuery(Product entity) { + + Query moreLikeThisQuery = getQueryBuilder() + .moreLikeThis() + .comparingField("productName") + .toEntity(entity) + .createQuery(); + + List results = getJpaQuery(moreLikeThisQuery).setProjection(ProjectionConstants.THIS, ProjectionConstants.SCORE) + .getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionByKeywordQuery(String text) { + + Query keywordQuery = getQueryBuilder() + .keyword() + .onFields("productName", "description") + .matching(text) + .createQuery(); + + List results = getJpaQuery(keywordQuery).getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionByMoreLikeThisQuery(Product entity) { + + Query moreLikeThisQuery = getQueryBuilder() + .moreLikeThis() + .comparingField("productName") + .toEntity(entity) + .createQuery(); + + List results = getJpaQuery(moreLikeThisQuery).setProjection(ProjectionConstants.THIS, ProjectionConstants.SCORE) + .getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionByCombinedQuery(String manufactorer, int memoryLow, int memoryTop, String extraFeature, String exclude) { + + Query combinedQuery = getQueryBuilder() + .bool() + .must(getQueryBuilder().keyword() + .onField("productName") + .matching(manufactorer) + .createQuery()) + .must(getQueryBuilder() + .range() + .onField("memory") + .from(memoryLow) + .to(memoryTop) + .createQuery()) + .should(getQueryBuilder() + .phrase() + .onField("description") + .sentence(extraFeature) + .createQuery()) + .must(getQueryBuilder() + .keyword() + .onField("productName") + .matching(exclude) + .createQuery()) + .not() + .createQuery(); + + List results = getJpaQuery(combinedQuery).getResultList(); + + return results; + } + + private FullTextQuery getJpaQuery(org.apache.lucene.search.Query luceneQuery) { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + + return fullTextEntityManager.createFullTextQuery(luceneQuery, Product.class); + } + + private QueryBuilder getQueryBuilder() { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + + return fullTextEntityManager.getSearchFactory() + .buildQueryBuilder() + .forEntity(Product.class) + .get(); + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/model/Product.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/model/Product.java new file mode 100644 index 0000000000..3ca020fe57 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/model/Product.java @@ -0,0 +1,94 @@ +package com.baeldung.hibernatesearch.model; + +import org.hibernate.search.annotations.*; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Indexed +@Table(name = "product") +public class Product { + + @Id + private int id; + + @Field(termVector = TermVector.YES) + private String productName; + + @Field(termVector = TermVector.YES) + private String description; + + @Field + private int memory; + + public Product(int id, String productName, int memory, String description) { + this.id = id; + this.productName = productName; + this.memory = memory; + this.description = description; + } + + public Product() { + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof Product)) + return false; + + Product product = (Product) o; + + if (id != product.id) + return false; + if (memory != product.memory) + return false; + if (!productName.equals(product.productName)) + return false; + return description.equals(product.description); + } + + @Override + public int hashCode() { + int result = id; + result = 31 * result + productName.hashCode(); + result = 31 * result + memory; + result = 31 * result + description.hashCode(); + return result; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public int getMemory() { + return memory; + } + + public void setMemory(int memory) { + this.memory = memory; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/spring-hibernate5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/manytomany/spring/PersistenceConfig.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/dao/IFooDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/dao/IFooDao.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/persistence/dao/IFooDao.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/dao/IFooDao.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/dao/common/AbstractDao.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/dao/common/AbstractHibernateDao.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/dao/common/IOperations.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/dao/common/IOperations.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/persistence/dao/common/IOperations.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/dao/common/IOperations.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/dao/impl/FooHibernateDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/dao/impl/FooHibernateDao.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/persistence/dao/impl/FooHibernateDao.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/dao/impl/FooHibernateDao.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/IEmployeeDao.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/IProjectDao.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/EmployeeDao.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/manytomany/dao/impl/ProjectDao.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/persistence/model/Foo.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/model/Foo.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/persistence/model/Foo.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/persistence/model/Foo.java diff --git a/spring-hibernate5/src/main/java/com/baeldung/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java similarity index 98% rename from spring-hibernate5/src/main/java/com/baeldung/spring/PersistenceConfig.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java index 74ac0a269e..e64f0a4efe 100644 --- a/spring-hibernate5/src/main/java/com/baeldung/spring/PersistenceConfig.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java @@ -21,7 +21,7 @@ import java.util.Properties; @Configuration @EnableTransactionManagement -@PropertySource({ "classpath:persistence-h2.properties" }) +@PropertySource({ "classpath:persistence-mysql.properties" }) @ComponentScan({ "com.baeldung.persistence" }) public class PersistenceConfig { diff --git a/spring-hibernate5/src/main/java/com/baeldung/spring/PersistenceXmlConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceXmlConfig.java similarity index 100% rename from spring-hibernate5/src/main/java/com/baeldung/spring/PersistenceXmlConfig.java rename to persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceXmlConfig.java diff --git a/spring-hibernate5/src/main/resources/hibernate5Config.xml b/persistence-modules/spring-hibernate-5/src/main/resources/hibernate5Config.xml similarity index 95% rename from spring-hibernate5/src/main/resources/hibernate5Config.xml rename to persistence-modules/spring-hibernate-5/src/main/resources/hibernate5Config.xml index 55546a862a..bbb61cb3e0 100644 --- a/spring-hibernate5/src/main/resources/hibernate5Config.xml +++ b/persistence-modules/spring-hibernate-5/src/main/resources/hibernate5Config.xml @@ -21,7 +21,7 @@ - + diff --git a/spring-hibernate5/src/main/resources/immutable.cfg.xml b/persistence-modules/spring-hibernate-5/src/main/resources/immutable.cfg.xml similarity index 100% rename from spring-hibernate5/src/main/resources/immutable.cfg.xml rename to persistence-modules/spring-hibernate-5/src/main/resources/immutable.cfg.xml diff --git a/spring-data-redis/src/main/resources/logback.xml b/persistence-modules/spring-hibernate-5/src/main/resources/logback.xml similarity index 100% rename from spring-data-redis/src/main/resources/logback.xml rename to persistence-modules/spring-hibernate-5/src/main/resources/logback.xml diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml b/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml new file mode 100644 index 0000000000..3c753a89af --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml @@ -0,0 +1,15 @@ + + + + + com.mysql.jdbc.Driver + tutorialmy5ql + jdbc:mysql://localhost:3306/spring_hibernate_many_to_many + tutorialuser + org.hibernate.dialect.MySQLDialect + thread + true + + diff --git a/spring-hibernate5/src/main/resources/persistence-h2.properties b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties similarity index 62% rename from spring-hibernate5/src/main/resources/persistence-h2.properties rename to persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties index 537626bc2a..915bc4317b 100644 --- a/spring-hibernate5/src/main/resources/persistence-h2.properties +++ b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties @@ -1,7 +1,7 @@ # jdbc.X jdbc.driverClassName=org.h2.Driver jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 -jdbc.user=sa +jdbc.eventGeneratedId=sa jdbc.pass=sa # hibernate.X @@ -9,5 +9,9 @@ hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.show_sql=false hibernate.hbm2ddl.auto=create-drop +# hibernate.search.X +hibernate.search.default.directory_provider = filesystem +hibernate.search.default.indexBase = /data/index/default + # envers.X envers.audit_table_suffix=_audit_log diff --git a/spring-hibernate5/src/main/resources/persistence-mysql.properties b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-mysql.properties similarity index 90% rename from spring-hibernate5/src/main/resources/persistence-mysql.properties rename to persistence-modules/spring-hibernate-5/src/main/resources/persistence-mysql.properties index 1180929b30..b3cfd31f46 100644 --- a/spring-hibernate5/src/main/resources/persistence-mysql.properties +++ b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-mysql.properties @@ -1,7 +1,7 @@ # jdbc.X jdbc.driverClassName=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/spring_hibernate5_01?createDatabaseIfNotExist=true -jdbc.user=tutorialuser +jdbc.eventGeneratedId=tutorialuser jdbc.pass=tutorialmy5ql # hibernate.X diff --git a/spring-hibernate5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java similarity index 60% rename from spring-hibernate5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java rename to persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java index 801ddcdb45..1572f23ed1 100644 --- a/spring-hibernate5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java @@ -1,15 +1,21 @@ package com.baeldung.hibernate.immutable; import com.baeldung.hibernate.immutable.entities.Event; +import com.baeldung.hibernate.immutable.entities.EventGeneratedId; import com.baeldung.hibernate.immutable.util.HibernateUtil; import com.google.common.collect.Sets; -import org.hibernate.CacheMode; import org.hibernate.Session; import org.junit.*; import org.junit.rules.ExpectedException; import javax.persistence.PersistenceException; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; + +/** + * Configured in: immutable.cfg.xml + */ public class HibernateImmutableIntegrationTest { private static Session session; @@ -19,10 +25,8 @@ public class HibernateImmutableIntegrationTest { @Before public void before() { - session = HibernateUtil.getSessionFactory().getCurrentSession(); + session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); - createEvent(); - session.setCacheMode(CacheMode.REFRESH); } @BeforeClass @@ -38,28 +42,39 @@ public class HibernateImmutableIntegrationTest { @Test public void addEvent() { Event event = new Event(); + event.setId(2L); event.setTitle("Public Event"); session.save(event); session.getTransaction().commit(); + session.close(); } @Test public void updateEvent() { + createEvent(); Event event = (Event) session.createQuery("FROM Event WHERE title='New Event'").list().get(0); event.setTitle("Private Event"); - session.saveOrUpdate(event); - session.getTransaction().commit(); + session.update(event); + session.flush(); + session.refresh(event); + session.close(); + + assertThat(event.getTitle(), equalTo("New Event")); + assertThat(event.getId(), equalTo(5L)); } @Test public void deleteEvent() { + createEvent(); Event event = (Event) session.createQuery("FROM Event WHERE title='New Event'").list().get(0); session.delete(event); session.getTransaction().commit(); + session.close(); } @Test public void addGuest() { + createEvent(); Event event = (Event) session.createQuery("FROM Event WHERE title='New Event'").list().get(0); String newGuest = "Sara"; event.getGuestList().add(newGuest); @@ -67,6 +82,7 @@ public class HibernateImmutableIntegrationTest { exception.expect(PersistenceException.class); session.save(event); session.getTransaction().commit(); + session.close(); } @Test @@ -80,10 +96,29 @@ public class HibernateImmutableIntegrationTest { session.getTransaction().commit(); } - public static void createEvent() { - Event event = new Event(); - event.setTitle("New Event"); - event.setGuestList(Sets.newHashSet("guest")); + @Test + public void updateEventGenerated() { + createEventGenerated(); + EventGeneratedId eventGeneratedId = (EventGeneratedId) session.createQuery("FROM EventGeneratedId WHERE name LIKE '%John%'").list().get(0); + + eventGeneratedId.setName("Mike"); + session.update(eventGeneratedId); + session.flush(); + session.refresh(eventGeneratedId); + session.close(); + + assertThat(eventGeneratedId.getName(), equalTo("John")); + assertThat(eventGeneratedId.getId(), equalTo(1L)); + } + + private static void createEvent() { + Event event = new Event(5L, "New Event", Sets.newHashSet("guest")); session.save(event); } + + private static void createEventGenerated() { + EventGeneratedId eventGeneratedId = new EventGeneratedId("John", "Doe"); + session.save(eventGeneratedId); + } + } diff --git a/spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java similarity index 73% rename from spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java rename to persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java index 61d821e85e..614de6d3ad 100644 --- a/spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java @@ -1,6 +1,5 @@ package com.baeldung.hibernate.manytomany; - import java.util.HashSet; import java.util.Set; import org.hibernate.Session; @@ -17,10 +16,8 @@ import com.baeldung.hibernate.manytomany.model.Employee; import com.baeldung.hibernate.manytomany.model.Project; import com.baeldung.manytomany.spring.PersistenceConfig; - - @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = {PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) public class HibernateManyToManyAnnotationJavaConfigMainIntegrationTest { @Autowired @@ -28,7 +25,6 @@ public class HibernateManyToManyAnnotationJavaConfigMainIntegrationTest { private Session session; - @Before public final void before() { session = sessionFactory.openSession(); @@ -43,11 +39,11 @@ public class HibernateManyToManyAnnotationJavaConfigMainIntegrationTest { @Test public final void whenEntitiesAreCreated_thenNoExceptions() { - Set projects = new HashSet(); - projects.add(new Project("IT Project")); - projects.add(new Project("Networking Project")); - session.persist(new Employee("Peter", "Oven", projects)); - session.persist(new Employee("Allan", "Norman", projects)); + Set projects = new HashSet(); + projects.add(new Project("IT Project")); + projects.add(new Project("Networking Project")); + session.persist(new Employee("Peter", "Oven", projects)); + session.persist(new Employee("Allan", "Norman", projects)); } } diff --git a/spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java similarity index 94% rename from spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java rename to persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java index 9a536a0f80..0073e181cc 100644 --- a/spring-hibernate5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java @@ -17,6 +17,9 @@ import com.baeldung.hibernate.manytomany.util.HibernateUtil; import com.baeldung.hibernate.manytomany.model.Employee; import com.baeldung.hibernate.manytomany.model.Project; +/** + * Configured in: manytomany.cfg.xml + */ public class HibernateManyToManyAnnotationMainIntegrationTest { private static SessionFactory sessionFactory; diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernatesearch/HibernateSearchIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernatesearch/HibernateSearchIntegrationTest.java new file mode 100644 index 0000000000..b69f8d3a60 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernatesearch/HibernateSearchIntegrationTest.java @@ -0,0 +1,187 @@ +package com.baeldung.hibernatesearch; + +import com.baeldung.hibernatesearch.model.Product; + +import static org.hamcrest.collection.IsIterableContainingInOrder.contains; +import static org.junit.Assert.*; + +import org.hibernate.search.jpa.FullTextEntityManager; +import org.hibernate.search.jpa.Search; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Commit; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { HibernateSearchConfig.class }, loader = AnnotationConfigContextLoader.class) +@Transactional +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class HibernateSearchIntegrationTest { + + @Autowired + ProductSearchDao dao; + + @PersistenceContext + private EntityManager entityManager; + + private List products; + + @Before + public void setupTestData() { + + products = Arrays.asList(new Product(1, "Apple iPhone X 256 GB", 256, "The current high-end smartphone from Apple, with lots of memory and also Face ID"), + new Product(2, "Apple iPhone X 128 GB", 128, "The current high-end smartphone from Apple, with Face ID"), new Product(3, "Apple iPhone 8 128 GB", 128, "The latest smartphone from Apple within the regular iPhone line, supporting wireless charging"), + new Product(4, "Samsung Galaxy S7 128 GB", 64, "A great Android smartphone"), new Product(5, "Microsoft Lumia 650 32 GB", 32, "A cheaper smartphone, coming with Windows Mobile"), + new Product(6, "Microsoft Lumia 640 32 GB", 32, "A cheaper smartphone, coming with Windows Mobile"), new Product(7, "Microsoft Lumia 630 16 GB", 16, "A cheaper smartphone, coming with Windows Mobile")); + } + + @Commit + @Test + public void testA_whenInitialTestDataInserted_thenSuccess() { + + for (int i = 0; i < products.size() - 1; i++) { + entityManager.persist(products.get(i)); + } + } + + @Test + public void testB_whenIndexInitialized_thenCorrectIndexSize() throws InterruptedException { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + fullTextEntityManager.createIndexer() + .startAndWait(); + int indexSize = fullTextEntityManager.getSearchFactory() + .getStatistics() + .getNumberOfIndexedEntities(Product.class.getName()); + + assertEquals(products.size() - 1, indexSize); + } + + @Commit + @Test + public void testC_whenAdditionalTestDataInserted_thenSuccess() { + + entityManager.persist(products.get(products.size() - 1)); + } + + @Test + public void testD_whenAdditionalTestDataInserted_thenIndexUpdatedAutomatically() { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + int indexSize = fullTextEntityManager.getSearchFactory() + .getStatistics() + .getNumberOfIndexedEntities(Product.class.getName()); + + assertEquals(products.size(), indexSize); + } + + @Test + public void testE_whenKeywordSearchOnName_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2)); + List results = dao.searchProductNameByKeywordQuery("iphone"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } + + @Test + public void testF_whenFuzzySearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2)); + List results = dao.searchProductNameByFuzzyQuery("iPhaen"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } + + @Test + public void testG_whenWildcardSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(4), products.get(5), products.get(6)); + List results = dao.searchProductNameByWildcardQuery("6*"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testH_whenPhraseSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(2)); + List results = dao.searchProductDescriptionByPhraseQuery("with wireless charging"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testI_whenSimpleQueryStringSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1)); + List results = dao.searchProductNameAndDescriptionBySimpleQueryStringQuery("Aple~2 + \"iPhone X\" + (256 | 128)"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testJ_whenRangeSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2), products.get(3)); + List results = dao.searchProductNameByRangeQuery(64, 256); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testK_whenMoreLikeThisSearch_thenCorrectMatchesInOrder() { + List expected = products; + List resultsWithScore = dao.searchProductNameByMoreLikeThisQuery(products.get(0)); + List results = new LinkedList(); + + for (Object[] resultWithScore : resultsWithScore) { + results.add((Product) resultWithScore[0]); + } + + assertThat(results, contains(expected.toArray())); + + } + + @Test + public void testL_whenKeywordSearchOnNameAndDescription_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2)); + List results = dao.searchProductNameAndDescriptionByKeywordQuery("iphone"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } + + @Test + public void testM_whenMoreLikeThisSearchOnProductNameAndDescription_thenCorrectMatchesInOrder() { + List expected = products; + List resultsWithScore = dao.searchProductNameAndDescriptionByMoreLikeThisQuery(products.get(0)); + List results = new LinkedList(); + + for (Object[] resultWithScore : resultsWithScore) { + results.add((Product) resultWithScore[0]); + } + + assertThat(results, contains(expected.toArray())); + } + + @Test + public void testN_whenCombinedSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(1), products.get(2)); + List results = dao.searchProductNameAndDescriptionByCombinedQuery("apple", 64, 128, "face id", "samsung"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } +} diff --git a/spring-hibernate5/src/test/java/com/baeldung/persistence/dao/common/HibernateDaoIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/dao/common/HibernateDaoIntegrationTest.java similarity index 100% rename from spring-hibernate5/src/test/java/com/baeldung/persistence/dao/common/HibernateDaoIntegrationTest.java rename to persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/persistence/dao/common/HibernateDaoIntegrationTest.java diff --git a/spring-jpa/.gitignore b/persistence-modules/spring-hibernate-5/src/test/resources/.gitignore similarity index 100% rename from spring-jpa/.gitignore rename to persistence-modules/spring-hibernate-5/src/test/resources/.gitignore diff --git a/spring-jpa/src/test/resources/.gitignore b/persistence-modules/spring-jpa/.gitignore similarity index 100% rename from spring-jpa/src/test/resources/.gitignore rename to persistence-modules/spring-jpa/.gitignore diff --git a/spring-jpa/README.md b/persistence-modules/spring-jpa/README.md similarity index 91% rename from spring-jpa/README.md rename to persistence-modules/spring-jpa/README.md index 70f4404f98..d93271164c 100644 --- a/spring-jpa/README.md +++ b/persistence-modules/spring-jpa/README.md @@ -14,6 +14,7 @@ - [Spring, Hibernate and a JNDI Datasource](http://www.baeldung.com/spring-persistence-jpa-jndi-datasource) - [Deleting Objects with Hibernate](http://www.baeldung.com/delete-with-hibernate) - [Self-Contained Testing Using an In-Memory Database](http://www.baeldung.com/spring-jpa-test-in-memory-database) +- [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories) ### Eclipse Config After importing the project into Eclipse, you may see the following error: diff --git a/spring-jpa/pom.xml b/persistence-modules/spring-jpa/pom.xml similarity index 94% rename from spring-jpa/pom.xml rename to persistence-modules/spring-jpa/pom.xml index 6a67d44b48..04c64fafc3 100644 --- a/spring-jpa/pom.xml +++ b/persistence-modules/spring-jpa/pom.xml @@ -13,6 +13,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../ @@ -113,6 +114,11 @@ guava ${guava.version} + + org.assertj + assertj-core + ${assertj.version} + @@ -180,6 +186,7 @@ 21.0 3.5 + 3.8.0 4.4.5 4.5.2 diff --git a/spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigL2Cache.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigL2Cache.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigL2Cache.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigL2Cache.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigXml.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigXml.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigXml.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigXml.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/SpringWebConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/SpringWebConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/SpringWebConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/SpringWebConfig.java diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java new file mode 100644 index 0000000000..439c6cb602 --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java @@ -0,0 +1,69 @@ +package org.baeldung.config; + +import java.util.Properties; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + +import org.baeldung.extended.persistence.dao.ExtendedRepositoryImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableJpaRepositories(basePackages = "org.baeldung.extended.persistence.dao", repositoryBaseClass = ExtendedRepositoryImpl.class) +@PropertySource("persistence-student-h2.properties") +@EnableTransactionManagement +public class StudentJPAH2Config { + + @Autowired + private Environment env; + + @Bean + public DataSource dataSource() { + final DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); + dataSource.setUrl(env.getProperty("jdbc.url")); + dataSource.setUsername(env.getProperty("jdbc.user")); + dataSource.setPassword(env.getProperty("jdbc.pass")); + + return dataSource; + } + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory() { + final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(dataSource()); + em.setPackagesToScan(new String[] { "org.baeldung.inmemory.persistence.model" }); + em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + em.setJpaProperties(additionalProperties()); + return em; + } + + @Bean + JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(entityManagerFactory); + return transactionManager; + } + + final Properties additionalProperties() { + final Properties hibernateProperties = new Properties(); + + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql")); + hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache")); + hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache")); + + return hibernateProperties; + } +} diff --git a/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java similarity index 94% rename from spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java index a40f180a62..8021691716 100644 --- a/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java @@ -18,7 +18,7 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration -@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao") +@EnableJpaRepositories(basePackages = "org.baeldung.inmemory.persistence.dao") @PropertySource("persistence-student.properties") @EnableTransactionManagement public class StudentJpaConfig { @@ -41,7 +41,7 @@ public class StudentJpaConfig { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" }); + em.setPackagesToScan(new String[] { "org.baeldung.inmemory.persistence.model" }); em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); em.setJpaProperties(additionalProperties()); return em; diff --git a/spring-jpa/src/main/java/org/baeldung/config/UserConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/UserConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/UserConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/UserConfig.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDao.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDao.java new file mode 100644 index 0000000000..180f54326e --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDao.java @@ -0,0 +1,29 @@ +package org.baeldung.dsrouting; + +import javax.sql.DataSource; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +/** + * Database access code for datasource routing example. + */ +public class ClientDao { + + private static final String SQL_GET_CLIENT_NAME = "select name from client"; + + private final JdbcTemplate jdbcTemplate; + + public ClientDao(DataSource datasource) { + this.jdbcTemplate = new JdbcTemplate(datasource); + } + + public String getClientName() { + return this.jdbcTemplate.query(SQL_GET_CLIENT_NAME, rowMapper) + .get(0); + } + + private static RowMapper rowMapper = (rs, rowNum) -> { + return rs.getString("name"); + }; +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java new file mode 100644 index 0000000000..997e461cde --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java @@ -0,0 +1,14 @@ +package org.baeldung.dsrouting; + +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; + +/** + * Returns thread bound client lookup key for current context. + */ +public class ClientDataSourceRouter extends AbstractRoutingDataSource { + + @Override + protected Object determineCurrentLookupKey() { + return ClientDatabaseContextHolder.getClientDatabase(); + } +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabase.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabase.java new file mode 100644 index 0000000000..619b8707d8 --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabase.java @@ -0,0 +1,7 @@ +package org.baeldung.dsrouting; + +public enum ClientDatabase { + + CLIENT_A, CLIENT_B + +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java new file mode 100644 index 0000000000..c08559e877 --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java @@ -0,0 +1,26 @@ +package org.baeldung.dsrouting; + +import org.springframework.util.Assert; + +/** + * Thread shared context to point to the datasource which should be used. This + * enables context switches between different clients. + */ +public class ClientDatabaseContextHolder { + + private static final ThreadLocal CONTEXT = new ThreadLocal<>(); + + public static void set(ClientDatabase clientDatabase) { + Assert.notNull(clientDatabase, "clientDatabase cannot be null"); + CONTEXT.set(clientDatabase); + } + + public static ClientDatabase getClientDatabase() { + return CONTEXT.get(); + } + + public static void clear() { + CONTEXT.remove(); + } + +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientService.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientService.java new file mode 100644 index 0000000000..4b63c6333c --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientService.java @@ -0,0 +1,21 @@ +package org.baeldung.dsrouting; + +/** + * Service layer code for datasource routing example. Here, the service methods are responsible + * for setting and clearing the context. + */ +public class ClientService { + + private final ClientDao clientDao; + + public ClientService(ClientDao clientDao) { + this.clientDao = clientDao; + } + + public String getClientName(ClientDatabase clientDb) { + ClientDatabaseContextHolder.set(clientDb); + String clientName = this.clientDao.getClientName(); + ClientDatabaseContextHolder.clear(); + return clientName; + } +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java new file mode 100644 index 0000000000..9c9c12029a --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java @@ -0,0 +1,12 @@ +package org.baeldung.extended.persistence.dao; + +import java.io.Serializable; +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.NoRepositoryBean; + +@NoRepositoryBean +public interface ExtendedRepository extends JpaRepository { + public List findByAttributeContainsText(String attributeName, String text); +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java new file mode 100644 index 0000000000..0dd32757d7 --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java @@ -0,0 +1,36 @@ +package org.baeldung.extended.persistence.dao; + +import java.io.Serializable; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; +import javax.transaction.Transactional; + +import org.springframework.data.jpa.repository.support.JpaEntityInformation; +import org.springframework.data.jpa.repository.support.SimpleJpaRepository; + +public class ExtendedRepositoryImpl extends SimpleJpaRepository implements ExtendedRepository { + + private EntityManager entityManager; + + public ExtendedRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) { + super(entityInformation, entityManager); + this.entityManager = entityManager; + } + + @Transactional + public List findByAttributeContainsText(String attributeName, String text) { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(getDomainClass()); + Root root = query.from(getDomainClass()); + query.select(root) + .where(builder.like(root. get(attributeName), "%" + text + "%")); + TypedQuery q = entityManager.createQuery(query); + return q.getResultList(); + } + +} diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java new file mode 100644 index 0000000000..7e2efc72bc --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java @@ -0,0 +1,6 @@ +package org.baeldung.extended.persistence.dao; + +import org.baeldung.inmemory.persistence.model.Student; + +public interface ExtendedStudentRepository extends ExtendedRepository { +} diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/dao/StudentRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java similarity index 57% rename from spring-jpa/src/main/java/org/baeldung/persistence/dao/StudentRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java index af484b442c..bfcf6f5cdc 100644 --- a/spring-jpa/src/main/java/org/baeldung/persistence/dao/StudentRepository.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java @@ -1,8 +1,7 @@ -package org.baeldung.persistence.dao; +package org.baeldung.inmemory.persistence.dao; +import org.baeldung.inmemory.persistence.model.Student; import org.springframework.data.jpa.repository.JpaRepository; -import org.baeldung.persistence.model.Student; - public interface StudentRepository extends JpaRepository { } diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/model/Student.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java similarity index 91% rename from spring-jpa/src/main/java/org/baeldung/persistence/model/Student.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java index 437eeac5bb..b50fe9122e 100644 --- a/spring-jpa/src/main/java/org/baeldung/persistence/model/Student.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package org.baeldung.inmemory.persistence.model; import javax.persistence.Entity; import javax.persistence.Id; diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/model/Bar.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Bar.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/model/Bar.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Bar.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/sqlfiles/Country.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/sqlfiles/Country.java new file mode 100644 index 0000000000..0555c8186c --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/sqlfiles/Country.java @@ -0,0 +1,33 @@ +package org.baeldung.sqlfiles; + +import static javax.persistence.GenerationType.IDENTITY; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Country { + + @Id + @GeneratedValue(strategy = IDENTITY) + private Integer id; + + @Column(nullable = false) + private String name; + + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + +} diff --git a/spring-jpa/src/main/java/org/baeldung/web/MainController.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/web/MainController.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/web/MainController.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/web/MainController.java diff --git a/spring-jpa/src/main/resources/context.xml b/persistence-modules/spring-jpa/src/main/resources/context.xml similarity index 100% rename from spring-jpa/src/main/resources/context.xml rename to persistence-modules/spring-jpa/src/main/resources/context.xml diff --git a/spring-hibernate3/src/main/resources/logback.xml b/persistence-modules/spring-jpa/src/main/resources/logback.xml similarity index 100% rename from spring-hibernate3/src/main/resources/logback.xml rename to persistence-modules/spring-jpa/src/main/resources/logback.xml diff --git a/spring-jpa/src/main/resources/persistence-h2.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-h2.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties diff --git a/spring-jpa/src/main/resources/persistence-jndi.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-jndi.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-jndi.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-jndi.properties diff --git a/spring-jpa/src/main/resources/persistence-multiple-db.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-multiple-db.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-multiple-db.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-multiple-db.properties diff --git a/spring-jpa/src/main/resources/persistence-mysql.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-mysql.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-mysql.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-mysql.properties diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties new file mode 100644 index 0000000000..e1d6bfa45a --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties @@ -0,0 +1,12 @@ +# jdbc.X +jdbc.driverClassName=org.h2.Driver +jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +jdbc.user=sa +# jdbc.pass= + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=false +hibernate.cache.use_query_cache=false \ No newline at end of file diff --git a/spring-jpa/src/main/resources/persistence-student.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-student.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-student.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-student.properties diff --git a/spring-jpa/src/main/resources/persistence.xml b/persistence-modules/spring-jpa/src/main/resources/persistence.xml similarity index 100% rename from spring-jpa/src/main/resources/persistence.xml rename to persistence-modules/spring-jpa/src/main/resources/persistence.xml diff --git a/spring-jpa/src/main/resources/server.xml b/persistence-modules/spring-jpa/src/main/resources/server.xml similarity index 100% rename from spring-jpa/src/main/resources/server.xml rename to persistence-modules/spring-jpa/src/main/resources/server.xml diff --git a/persistence-modules/spring-jpa/src/main/resources/sqlfiles.properties b/persistence-modules/spring-jpa/src/main/resources/sqlfiles.properties new file mode 100644 index 0000000000..0bea6adad1 --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/resources/sqlfiles.properties @@ -0,0 +1 @@ +spring.jpa.hibernate.ddl-auto=none \ No newline at end of file diff --git a/spring-jpa/src/main/webapp/WEB-INF/views/jsp/index.jsp b/persistence-modules/spring-jpa/src/main/webapp/WEB-INF/views/jsp/index.jsp similarity index 100% rename from spring-jpa/src/main/webapp/WEB-INF/views/jsp/index.jsp rename to persistence-modules/spring-jpa/src/main/webapp/WEB-INF/views/jsp/index.jsp diff --git a/spring-jpa/src/test/java/META-INF/persistence.xml b/persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml similarity index 100% rename from spring-jpa/src/test/java/META-INF/persistence.xml rename to persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java new file mode 100644 index 0000000000..f81247e3cd --- /dev/null +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java @@ -0,0 +1,53 @@ +package org.baeldung.dsrouting; + +import static org.junit.Assert.assertEquals; + +import javax.sql.DataSource; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = DataSourceRoutingTestConfiguration.class) +public class DataSourceRoutingIntegrationTest { + + @Autowired + DataSource routingDatasource; + + @Autowired + ClientService clientService; + + @Before + public void setup() { + final String SQL_CLIENT_A = "insert into client (id, name) values (1, 'CLIENT A')"; + final String SQL_CLIENT_B = "insert into client (id, name) values (2, 'CLIENT B')"; + + JdbcTemplate jdbcTemplate = new JdbcTemplate(); + jdbcTemplate.setDataSource(routingDatasource); + + ClientDatabaseContextHolder.set(ClientDatabase.CLIENT_A); + jdbcTemplate.execute(SQL_CLIENT_A); + ClientDatabaseContextHolder.clear(); + + ClientDatabaseContextHolder.set(ClientDatabase.CLIENT_B); + jdbcTemplate.execute(SQL_CLIENT_B); + ClientDatabaseContextHolder.clear(); + } + + @Test + public void givenClientDbs_whenContextsSwitch_thenRouteToCorrectDatabase() throws Exception { + + // test ACME WIDGETS + String clientName = clientService.getClientName(ClientDatabase.CLIENT_A); + assertEquals(clientName, "CLIENT A"); + + // test WIDGETS_ARE_US + clientName = clientService.getClientName(ClientDatabase.CLIENT_B); + assertEquals(clientName, "CLIENT B"); + } +} diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java new file mode 100644 index 0000000000..dee9d58722 --- /dev/null +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java @@ -0,0 +1,51 @@ +package org.baeldung.dsrouting; + +import java.util.HashMap; +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; + +@Configuration +public class DataSourceRoutingTestConfiguration { + + @Bean + public ClientService clientService() { + return new ClientService(new ClientDao(clientDatasource())); + } + + @Bean + public DataSource clientDatasource() { + Map targetDataSources = new HashMap<>(); + DataSource clientADatasource = clientADatasource(); + DataSource clientBDatasource = clientBDatasource(); + targetDataSources.put(ClientDatabase.CLIENT_A, clientADatasource); + targetDataSources.put(ClientDatabase.CLIENT_B, clientBDatasource); + + ClientDataSourceRouter clientRoutingDatasource = new ClientDataSourceRouter(); + clientRoutingDatasource.setTargetDataSources(targetDataSources); + clientRoutingDatasource.setDefaultTargetDataSource(clientADatasource); + return clientRoutingDatasource; + } + + private DataSource clientADatasource() { + EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder(); + return dbBuilder.setType(EmbeddedDatabaseType.H2) + .setName("CLIENT_A") + .addScript("classpath:dsrouting-db.sql") + .build(); + } + + private DataSource clientBDatasource() { + EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder(); + return dbBuilder.setType(EmbeddedDatabaseType.H2) + .setName("CLIENT_B") + .addScript("classpath:dsrouting-db.sql") + .build(); + } +} diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Bar.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Bar.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Bar.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Bar.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Baz.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Baz.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Baz.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Baz.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Foo.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Foo.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Foo.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Foo.java diff --git a/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java new file mode 100644 index 0000000000..0970daa0ee --- /dev/null +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java @@ -0,0 +1,39 @@ +package org.baeldung.persistence.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import javax.annotation.Resource; + +import org.baeldung.config.StudentJPAH2Config; +import org.baeldung.extended.persistence.dao.ExtendedStudentRepository; +import org.baeldung.inmemory.persistence.model.Student; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { StudentJPAH2Config.class}) +public class ExtendedStudentRepositoryIntegrationTest { + @Resource + private ExtendedStudentRepository extendedStudentRepository; + + @Before + public void setup(){ + Student student = new Student(1, "john"); + extendedStudentRepository.save(student); + Student student2 = new Student(2, "johnson"); + extendedStudentRepository.save(student2); + Student student3 = new Student(3, "tom"); + extendedStudentRepository.save(student3); + } + + @Test + public void givenStudents_whenFindByName_thenGetOk(){ + List students = extendedStudentRepository.findByAttributeContainsText("name", "john"); + assertThat(students.size()).isEqualTo(2); + } +} diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java similarity index 90% rename from spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java index 1fcc4be45d..8380ab5434 100644 --- a/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java +++ b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java @@ -1,8 +1,8 @@ package org.baeldung.persistence.repository; import org.baeldung.config.StudentJpaConfig; -import org.baeldung.persistence.dao.StudentRepository; -import org.baeldung.persistence.model.Student; +import org.baeldung.inmemory.persistence.dao.StudentRepository; +import org.baeldung.inmemory.persistence.model.Student; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java diff --git a/spring-security-rest-full/.gitignore b/persistence-modules/spring-jpa/src/test/resources/.gitignore similarity index 100% rename from spring-security-rest-full/.gitignore rename to persistence-modules/spring-jpa/src/test/resources/.gitignore diff --git a/persistence-modules/spring-jpa/src/test/resources/dsrouting-db.sql b/persistence-modules/spring-jpa/src/test/resources/dsrouting-db.sql new file mode 100644 index 0000000000..c9ca52907a --- /dev/null +++ b/persistence-modules/spring-jpa/src/test/resources/dsrouting-db.sql @@ -0,0 +1,5 @@ +create table client ( + id numeric, + name varchar(50), + constraint pk_client primary key (id) +); \ No newline at end of file diff --git a/spring-jpa/src/test/resources/persistence-student.properties b/persistence-modules/spring-jpa/src/test/resources/persistence-student.properties similarity index 100% rename from spring-jpa/src/test/resources/persistence-student.properties rename to persistence-modules/spring-jpa/src/test/resources/persistence-student.properties diff --git a/pom.xml b/pom.xml index dfa7e09acc..c8fa30e8c9 100644 --- a/pom.xml +++ b/pom.xml @@ -28,6 +28,9 @@ + asm + atomix + apache-cayenne aws akka-streams algorithms @@ -45,25 +48,29 @@ core-java core-java-8 core-java-concurrency - couchbase-sdk + couchbase + cas/cas-server + cas/cas-secured-app deltaspike dozer + ethereumj + feign flyway - + - - groovy-spock + geotools + testing-modules/groovy-spock gson guava - guava18 - guava19 - guava21 + guava-modules/guava-18 + guava-modules/guava-19 + guava-modules/guava-21 guice disruptor @@ -78,12 +85,12 @@ immutables jackson - + vavr javax-servlets javaxval jaxb - jee7 + jee-7 jjwt jpa-storedprocedure @@ -91,47 +98,51 @@ json-path json jsoup - junit5 + testing-modules/junit-5 jws libraries - libraries-data - log-mdc - log4j - log4j2 + libraries-data + linkrest + logging-modules/log-mdc + logging-modules/log4j + logging-modules/log4j2 + logging-modules/logback lombok mapstruct metrics mesos-marathon - mockito - mockito2 - mocks + testing-modules/mockito + testing-modules/mockito-2 + testing-modules/mocks mustache noexception + osgi orika patterns pdf protobuffer - querydsl + persistence-modules/querydsl reactor-core - redis - rest-assured - rest-testing + persistence-modules/redis + testing-modules/rest-assured + testing-modules/rest-testing resteasy rxjava spring-swagger-codegen - selenium-junit-testng - solr + testing-modules/selenium-junit-testng + persistence-modules/solr spark-java spring-5-mvc + spring-acl spring-activiti spring-akka spring-amqp @@ -141,31 +152,34 @@ spring-batch spring-bom spring-boot + spring-boot-keycloak + spring-boot-bootstrap spring-cloud-data-flow spring-cloud spring-core spring-cucumber spring-aop - spring-data-cassandra + persistence-modules/spring-data-cassandra spring-data-couchbase-2 - spring-data-dynamodb + persistence-modules/spring-data-dynamodb spring-data-elasticsearch spring-data-mongodb - spring-data-neo4j - spring-data-redis + persistence-modules/spring-data-neo4j + persistence-modules/spring-data-redis spring-data-rest - spring-data-solr + persistence-modules/spring-data-solr spring-dispatcher-servlet spring-exceptions spring-freemarker - spring-hibernate3 + persistence-modules/spring-hibernate-3 spring-hibernate4 - spring-hibernate5 + persistence-modules/spring-hibernate-5 spring-integration spring-jersey + spring-jmeter-jenkins spring-jms spring-jooq - spring-jpa + persistence-modules/spring-jpa spring-kafka spring-katharsis spring-ldap @@ -184,6 +198,8 @@ spring-quartz spring-rest-angular spring-rest-docs + spring-rest-full + spring-rest-query-language spring-rest spring-rest-simple spring-security-cache-control @@ -205,7 +221,6 @@ spring-security-mvc-socket spring-security-rest-basic-auth spring-security-rest-custom - spring-security-rest-full spring-security-rest spring-security-sso spring-security-x509 @@ -219,30 +234,36 @@ spring-zuul spring-reactor spring-vertx + + spring-rest-embedded-tomcat - testing - testng + testing-modules/testing + testing-modules/testng video-tutorials xml - xmlunit2 - struts2 + xmlunit-2 + struts-2 apache-velocity apache-solrj rabbitmq vertx - spring-data-gemfire + persistence-modules/spring-data-gemfire mybatis spring-drools drools - liquibase + persistence-modules/liquibase spring-boot-property-exp - mockserver + testing-modules/mockserver undertow vertx-and-rxjava + saas + deeplearning4j + spring-boot-admin + lucene @@ -325,7 +346,7 @@ **/JdbcTest.java **/*LiveTest.java - true + diff --git a/ratpack/README.md b/ratpack/README.md index 8215f74148..02b91da0bd 100644 --- a/ratpack/README.md +++ b/ratpack/README.md @@ -3,3 +3,5 @@ - [Introduction to Ratpack](http://www.baeldung.com/ratpack) - [Ratpack Google Guice Integration](http://www.baeldung.com/ratpack-google-guice) - [Ratpack Integration with Spring Boot](http://www.baeldung.com/ratpack-spring-boot) +- [Ratpack with Hystrix](http://www.baeldung.com/ratpack-hystrix) + diff --git a/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2IntegrationTest.java b/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2IntegrationTest.java deleted file mode 100644 index 13ba3ccac9..0000000000 --- a/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2IntegrationTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.baeldung.restassured; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.post; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static org.hamcrest.Matchers.hasItems; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import static io.restassured.RestAssured.get; - -import com.github.tomakehurst.wiremock.WireMockServer; - -public class RestAssured2IntegrationTest { - private WireMockServer wireMockServer = new WireMockServer(); - - private static final String EVENTS_PATH = "/odds"; - private static final String APPLICATION_JSON = "application/json"; - private static final String ODDS = getJson(); - - @Before - public void before() throws Exception { - System.out.println("Setting up!"); - wireMockServer.start(); - configureFor("localhost", 8080); - stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn( - aResponse().withStatus(200) - .withHeader("Content-Type", APPLICATION_JSON) - .withBody(ODDS))); - } - - @Test - public void givenUrl_whenVerifiesOddPricesAccuratelyByStatus_thenCorrect() { - get("/odds").then().body("odds.findAll { it.status > 0 }.price", - hasItems(5.25f, 1.2f)); - } - - private static String getJson() { - - return Util.inputStreamToString(new RestAssured2IntegrationTest().getClass() - .getResourceAsStream("/odds.json")); - - } - - @After - public void after() throws Exception { - System.out.println("Running: tearDown"); - wireMockServer.stop(); - } - -} diff --git a/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredIntegrationTest.java b/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredIntegrationTest.java deleted file mode 100644 index f14d9920b6..0000000000 --- a/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredIntegrationTest.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.baeldung.restassured; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static io.restassured.RestAssured.get; -import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath; -import static io.restassured.module.jsv.JsonSchemaValidatorSettings.settings; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasItems; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.github.fge.jsonschema.SchemaVersion; -import com.github.fge.jsonschema.cfg.ValidationConfiguration; -import com.github.fge.jsonschema.main.JsonSchemaFactory; -import com.github.tomakehurst.wiremock.WireMockServer; - -public class RestAssuredIntegrationTest { - - private WireMockServer wireMockServer = new WireMockServer(); - private static final String EVENTS_PATH = "/events?id=390"; - private static final String APPLICATION_JSON = "application/json"; - private static final String GAME_ODDS = getEventJson(); - - @Before - public void before() throws Exception { - System.out.println("Setting up!"); - wireMockServer.start(); - configureFor("localhost", 8080); - stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn( - aResponse().withStatus(200) - .withHeader("Content-Type", APPLICATION_JSON) - .withBody(GAME_ODDS))); - } - - @Test - public void givenUrl_whenCheckingFloatValuePasses_thenCorrect() { - get("/events?id=390").then().assertThat() - .body("odd.ck", equalTo(12.2f)); - } - - @Test - public void givenUrl_whenSuccessOnGetsResponseAndJsonHasRequiredKV_thenCorrect() { - - get("/events?id=390").then().statusCode(200).assertThat() - .body("id", equalTo("390")); - - } - - @Test - public void givenUrl_whenJsonResponseHasArrayWithGivenValuesUnderKey_thenCorrect() { - get("/events?id=390").then().assertThat() - .body("odds.price", hasItems("1.30", "5.25", "2.70", "1.20")); - } - - @Test - public void givenUrl_whenJsonResponseConformsToSchema_thenCorrect() { - - get("/events?id=390").then().assertThat() - .body(matchesJsonSchemaInClasspath("event_0.json")); - } - - @Test - public void givenUrl_whenValidatesResponseWithInstanceSettings_thenCorrect() { - JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory - .newBuilder() - .setValidationConfiguration( - ValidationConfiguration.newBuilder() - .setDefaultVersion(SchemaVersion.DRAFTV4) - .freeze()).freeze(); - - get("/events?id=390") - .then() - .assertThat() - .body(matchesJsonSchemaInClasspath("event_0.json").using( - jsonSchemaFactory)); - - } - - @Test - public void givenUrl_whenValidatesResponseWithStaticSettings_thenCorrect() { - - get("/events?id=390") - .then() - .assertThat() - .body(matchesJsonSchemaInClasspath("event_0.json").using( - settings().with().checkedValidation(false))); - } - - @After - public void after() throws Exception { - System.out.println("Running: tearDown"); - wireMockServer.stop(); - } - - private static String getEventJson() { - return Util.inputStreamToString(RestAssuredIntegrationTest.class - .getResourceAsStream("/event_0.json")); - } - -} diff --git a/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2IntegrationTest.java b/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2IntegrationTest.java deleted file mode 100644 index b77f24b15f..0000000000 --- a/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2IntegrationTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.baeldung.restassured; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.post; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static org.hamcrest.Matchers.hasItems; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import static io.restassured.RestAssured.get; - -import com.github.tomakehurst.wiremock.WireMockServer; - -public class RestAssuredXML2IntegrationTest { - private WireMockServer wireMockServer = new WireMockServer(); - - private static final String EVENTS_PATH = "/teachers"; - private static final String APPLICATION_XML = "application/xml"; - private static final String TEACHERS = getXml(); - - @Before - public void before() throws Exception { - System.out.println("Setting up!"); - wireMockServer.start(); - configureFor("localhost", 8080); - stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn( - aResponse().withStatus(200) - .withHeader("Content-Type", APPLICATION_XML) - .withBody(TEACHERS))); - } - @Test - public void givenUrl_whenVerifiesScienceTeacherFromXml_thenCorrect() { - get("/teachers") - .then() - .body("teachers.teacher.find { it.@department == 'science' }.subject", - hasItems("math", "physics")); - } - private static String getXml() { - - return Util - .inputStreamToString(new RestAssuredXML2IntegrationTest().getClass().getResourceAsStream("/teachers.xml")); - -} - @After -public void after() throws Exception { - System.out.println("Running: tearDown"); - wireMockServer.stop(); -} - -} diff --git a/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLIntegrationTest.java b/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLIntegrationTest.java deleted file mode 100644 index 10aef63cdb..0000000000 --- a/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLIntegrationTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.baeldung.restassured; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.post; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static io.restassured.RestAssured.post; -import static io.restassured.RestAssured.get; -import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath; -import static io.restassured.module.jsv.JsonSchemaValidatorSettings.settings; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasItems; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.xml.HasXPath.hasXPath; - -import java.io.FileNotFoundException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.github.fge.jsonschema.SchemaVersion; -import com.github.fge.jsonschema.cfg.ValidationConfiguration; -import com.github.fge.jsonschema.main.JsonSchemaFactory; -import com.github.tomakehurst.wiremock.WireMockServer; -public class RestAssuredXMLIntegrationTest { - private WireMockServer wireMockServer = new WireMockServer(); - private static final String EVENTS_PATH = "/employees"; - private static final String APPLICATION_XML = "application/xml"; - private static final String EMPLOYEES = getXml(); - - @Before - public void before() throws Exception { - System.out.println("Setting up!"); - wireMockServer.start(); - configureFor("localhost", 8080); - stubFor(post(urlEqualTo(EVENTS_PATH)).willReturn( - aResponse().withStatus(200) - .withHeader("Content-Type", APPLICATION_XML) - .withBody(EMPLOYEES))); - } - @Test - public void givenUrl_whenXmlResponseValueTestsEqual_thenCorrect() { - post("/employees").then().assertThat() - .body("employees.employee.first-name", equalTo("Jane")); - } - - @Test - public void givenUrl_whenMultipleXmlValuesTestEqual_thenCorrect() { - post("/employees").then().assertThat() - .body("employees.employee.first-name", equalTo("Jane")) - .body("employees.employee.last-name", equalTo("Daisy")) - .body("employees.employee.sex", equalTo("f")); - } - - @Test - public void givenUrl_whenMultipleXmlValuesTestEqualInShortHand_thenCorrect() { - post("/employees") - .then() - .assertThat() - .body("employees.employee.first-name", equalTo("Jane"), - "employees.employee.last-name", equalTo("Daisy"), - "employees.employee.sex", equalTo("f")); - } - - @Test - public void givenUrl_whenValidatesXmlUsingXpath_thenCorrect() { - post("/employees") - .then() - .assertThat() - .body(hasXPath("/employees/employee/first-name", - containsString("Ja"))); - - } - - @Test - public void givenUrl_whenValidatesXmlUsingXpath2_thenCorrect() { - post("/employees") - .then() - .assertThat() - .body(hasXPath("/employees/employee/first-name[text()='Jane']")); - - } - - - private static String getXml() { - - return Util - .inputStreamToString(new RestAssuredXMLIntegrationTest().getClass().getResourceAsStream("/employees.xml")); - -} - @After -public void after() throws Exception { - System.out.println("Running: tearDown"); - wireMockServer.stop(); -} -} diff --git a/rest-assured/src/test/java/com/baeldung/restassured/Util.java b/rest-assured/src/test/java/com/baeldung/restassured/Util.java deleted file mode 100644 index c75c52eb34..0000000000 --- a/rest-assured/src/test/java/com/baeldung/restassured/Util.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.baeldung.restassured; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -public class Util { - public static String inputStreamToString(InputStream is) { - BufferedReader br = null; - StringBuilder sb = new StringBuilder(); - - String line; - try { - - br = new BufferedReader(new InputStreamReader(is)); - while ((line = br.readLine()) != null) { - sb.append(line); - } - - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (br != null) { - try { - br.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - return sb.toString(); - - } -} diff --git a/rest-with-spark-java/README.md b/rest-with-spark-java/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/rest-with-spark-java/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/rmi/README.md b/rmi/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/rmi/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/rmi/client.policy b/rmi/client.policy new file mode 100644 index 0000000000..5d74bde76d --- /dev/null +++ b/rmi/client.policy @@ -0,0 +1,3 @@ +grant { + permission java.security.AllPermission; +}; \ No newline at end of file diff --git a/rmi/server.policy b/rmi/server.policy new file mode 100644 index 0000000000..5d74bde76d --- /dev/null +++ b/rmi/server.policy @@ -0,0 +1,3 @@ +grant { + permission java.security.AllPermission; +}; \ No newline at end of file diff --git a/rmi/src/org/baeldung/Client.java b/rmi/src/org/baeldung/Client.java new file mode 100644 index 0000000000..0376952bab --- /dev/null +++ b/rmi/src/org/baeldung/Client.java @@ -0,0 +1,20 @@ +package org.baeldung; + +import java.rmi.NotBoundException; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; + +public class Client { + public static void main(String[] args) throws RemoteException, NotBoundException { + System.setProperty("java.security.policy", "file:./client.policy"); + if (System.getSecurityManager() == null) { + System.setSecurityManager(new SecurityManager()); + } + String name = "RandomNumberGenerator"; + Registry registry = LocateRegistry.getRegistry(); + RandomNumberGenerator randomNumberGenerator = (RandomNumberGenerator) registry.lookup(name); + int number = randomNumberGenerator.get(); + System.out.println("Received random number:" + number); + } +} diff --git a/rmi/src/org/baeldung/RandomNumberGenerator.java b/rmi/src/org/baeldung/RandomNumberGenerator.java new file mode 100644 index 0000000000..50e49d2652 --- /dev/null +++ b/rmi/src/org/baeldung/RandomNumberGenerator.java @@ -0,0 +1,8 @@ +package org.baeldung; + +import java.rmi.Remote; +import java.rmi.RemoteException; + +public interface RandomNumberGenerator extends Remote{ + int get() throws RemoteException; +} diff --git a/rmi/src/org/baeldung/RandomNumberGeneratorEngine.java b/rmi/src/org/baeldung/RandomNumberGeneratorEngine.java new file mode 100644 index 0000000000..04d90b2ff9 --- /dev/null +++ b/rmi/src/org/baeldung/RandomNumberGeneratorEngine.java @@ -0,0 +1,10 @@ +package org.baeldung; + +import java.rmi.RemoteException; + +public class RandomNumberGeneratorEngine implements RandomNumberGenerator { + @Override + public int get() throws RemoteException { + return (int) (100 * Math.random()); + } +} diff --git a/rmi/src/org/baeldung/Server.java b/rmi/src/org/baeldung/Server.java new file mode 100644 index 0000000000..8e613cb6bb --- /dev/null +++ b/rmi/src/org/baeldung/Server.java @@ -0,0 +1,22 @@ +package org.baeldung; + +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; + +public class Server { + public static void main(String[] args) throws RemoteException { + System.setProperty("java.security.policy", "file:./server.policy"); + if (System.getSecurityManager() == null) { + System.setSecurityManager(new SecurityManager()); + } + String name = "RandomNumberGenerator"; + RandomNumberGenerator randomNumberGenerator = new RandomNumberGeneratorEngine(); + RandomNumberGenerator stub = + (RandomNumberGenerator) UnicastRemoteObject.exportObject(randomNumberGenerator, 0); + Registry registry = LocateRegistry.getRegistry(); + registry.rebind(name, stub); + System.out.println("RandomNumberGenerator bound"); + } +} diff --git a/rule-engines/README.md b/rule-engines/README.md new file mode 100644 index 0000000000..6d3c0e93b4 --- /dev/null +++ b/rule-engines/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [List of Rules Engines in Java](http://www.baeldung.com/java-rule-engines) diff --git a/rxjava/README.md b/rxjava/README.md index 7670dd4ed3..c88ec36991 100644 --- a/rxjava/README.md +++ b/rxjava/README.md @@ -2,3 +2,10 @@ - [Dealing with Backpressure with RxJava](http://www.baeldung.com/rxjava-backpressure) - [How to Test RxJava?](http://www.baeldung.com/rxjava-testing) +- [Implementing Custom Operators in RxJava](http://www.baeldung.com/rxjava-custom-operators) +- [Introduction to RxJava](http://www.baeldung.com/rx-java) +- [RxJava and Error Handling](http://www.baeldung.com/rxjava-error-handling) +- [Observable Utility Operators in RxJava](http://www.baeldung.com/rxjava-observable-operators) +- [Introduction to rxjava-jdbc](http://www.baeldung.com/rxjava-jdbc) +- [Schedulers in RxJava](http://www.baeldung.com/rxjava-schedulers) +- [Mathematical and Aggregate Operators in RxJava](http://www.baeldung.com/rxjava-math) diff --git a/rxjava/pom.xml b/rxjava/pom.xml index 578eda3fcf..0f950914ff 100644 --- a/rxjava/pom.xml +++ b/rxjava/pom.xml @@ -3,7 +3,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung rxjava 1.0-SNAPSHOT @@ -19,10 +18,53 @@ rxjava ${rx.java.version} + + + io.reactivex.rxjava2 + rxjava + 2.1.3 + + + + io.reactivex + rxjava-math + 1.0.0 + + + + com.jayway.awaitility + awaitility + 1.7.0 + + + com.github.davidmoten + rxjava-jdbc + ${rx.java.jdbc.version} + + + com.h2database + h2 + ${h2.version} + runtime + + + org.assertj + assertj-core + ${assertj.version} + + + com.google.guava + guava + 22.0 + test + + 3.8.0 1.2.5 + 0.7.11 + 1.4.196 diff --git a/rxjava/src/main/java/com/baelding/rxjava/ComputeFunction.java b/rxjava/src/main/java/com/baeldung/rxjava/ComputeFunction.java similarity index 97% rename from rxjava/src/main/java/com/baelding/rxjava/ComputeFunction.java rename to rxjava/src/main/java/com/baeldung/rxjava/ComputeFunction.java index 924862ab37..7f9787a9d5 100644 --- a/rxjava/src/main/java/com/baelding/rxjava/ComputeFunction.java +++ b/rxjava/src/main/java/com/baeldung/rxjava/ComputeFunction.java @@ -1,4 +1,4 @@ -package com.baelding.rxjava; +package com.baeldung.rxjava; import rx.Observable; diff --git a/rxjava/src/main/java/com/baeldung/rxjava/ConnectableObservableImpl.java b/rxjava/src/main/java/com/baeldung/rxjava/ConnectableObservableImpl.java new file mode 100644 index 0000000000..a3e20a33f0 --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/ConnectableObservableImpl.java @@ -0,0 +1,22 @@ +package com.baeldung.rxjava; + +import rx.Observable; +import rx.observables.ConnectableObservable; + +import java.util.concurrent.TimeUnit; + +public class ConnectableObservableImpl { + + public static void main(String[] args) throws InterruptedException { + + ConnectableObservable connectable + = Observable.interval(200, TimeUnit.MILLISECONDS).publish(); + connectable.subscribe(System.out::println); + + System.out.println("Connect"); + connectable.connect(); + + Thread.sleep(500); + System.out.println("Sleep"); + } +} diff --git a/rxjava/src/main/java/com/baeldung/rxjava/ObservableImpl.java b/rxjava/src/main/java/com/baeldung/rxjava/ObservableImpl.java new file mode 100644 index 0000000000..305aba6381 --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/ObservableImpl.java @@ -0,0 +1,81 @@ +package com.baeldung.rxjava; + +import rx.Observable; +import rx.observables.BlockingObservable; + +import java.util.Arrays; +import java.util.List; + +public class ObservableImpl { + + private static Integer[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + private static String[] letters = {"a", "b", "c", "d", "e", "f", "g", "h", "i"}; + private static String[] titles = {"title"}; + private static List titleList = Arrays.asList(titles); + + static Observable getTitle() { + return Observable.from(titleList); + } + + public static void main(String[] args) { + + System.out.println("-------Just-----------"); + Observable observable = Observable.just("Hello"); + observable.subscribe( + System.out::println, //onNext + Throwable::printStackTrace, //onError + () -> System.out.println("onCompleted") //onCompleted + ); + + BlockingObservable blockingObservable = observable.toBlocking(); + + System.out.println(); + System.out.println("-------Map-----------"); + Observable.from(letters) + .map(String::toUpperCase) + .subscribe(System.out::print); + + System.out.println(); + System.out.println("-------FlatMap-----------"); + Observable.just("book1", "book2") + .flatMap(s -> getTitle()) + .subscribe(System.out::print); + + System.out.println(); + System.out.println("--------Scan----------"); + Observable.from(letters) + .scan(new StringBuilder(), StringBuilder::append) + .subscribe(System.out::println); + + System.out.println(); + System.out.println("------GroubBy------------"); + Observable.from(numbers) + .groupBy(i -> 0 == (i % 2) ? "EVEN" : "ODD") + .subscribe((group) -> group.subscribe((number) -> { + System.out.println(group.getKey() + " : " + number); + })); + + System.out.println(); + System.out.println("-------Filter-----------"); + Observable.from(numbers) + .filter(i -> (i % 2 == 1)) + .subscribe(System.out::println); + + System.out.println("------DefaultIfEmpty------------"); + Observable.empty() + .defaultIfEmpty("Observable is empty") + .subscribe(System.out::println); + + System.out.println("------DefaultIfEmpty-2-----------"); + Observable.from(letters) + .defaultIfEmpty("Observable is empty") + .first() + .subscribe(System.out::println); + + System.out.println("-------TakeWhile-----------"); + Observable.from(numbers) + .takeWhile(i -> i < 5) + .subscribe(System.out::println); + } +} \ No newline at end of file diff --git a/rxjava/src/main/java/com/baeldung/rxjava/ResourceManagement.java b/rxjava/src/main/java/com/baeldung/rxjava/ResourceManagement.java new file mode 100644 index 0000000000..272442098f --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/ResourceManagement.java @@ -0,0 +1,30 @@ +package com.baeldung.rxjava; + +import rx.Observable; + +public class ResourceManagement { + + public static void main(String[] args) { + + Observable values = Observable.using( + () -> { + String resource = "MyResource"; + System.out.println("Leased: " + resource); + return resource; + }, + r -> Observable.create(o -> { + for (Character c : r.toCharArray()) { + o.onNext(c); + } + o.onCompleted(); + }), + r -> System.out.println("Disposed: " + r) + ); + + values.subscribe( + System.out::println, + System.out::println + ); + } +} + diff --git a/rxjava/src/main/java/com/baeldung/rxjava/SingleImpl.java b/rxjava/src/main/java/com/baeldung/rxjava/SingleImpl.java new file mode 100644 index 0000000000..f0fda5d4df --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/SingleImpl.java @@ -0,0 +1,18 @@ +package com.baeldung.rxjava; + +import rx.Observable; +import rx.Single; + +public class SingleImpl { + + public static void main(String[] args) { + + Single single = Observable.just("Hello") + .toSingle() + .doOnSuccess(System.out::print) + .doOnError(e -> { + throw new RuntimeException(e.getMessage()); + }); + single.subscribe(); + } +} diff --git a/rxjava/src/main/java/com/baeldung/rxjava/SubjectImpl.java b/rxjava/src/main/java/com/baeldung/rxjava/SubjectImpl.java new file mode 100644 index 0000000000..ceef3ab5f3 --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/SubjectImpl.java @@ -0,0 +1,73 @@ +package com.baeldung.rxjava; + +import rx.Observer; +import rx.subjects.PublishSubject; + +public class SubjectImpl { + + static Integer subscriber1 = 0; + static Integer subscriber2 = 0; + + private static Integer subjectMethod() { + PublishSubject subject = PublishSubject.create(); + + subject.subscribe(getFirstObserver()); + + subject.onNext(1); + subject.onNext(2); + subject.onNext(3); + + subject.subscribe(getSecondObserver()); + + subject.onNext(4); + subject.onCompleted(); + return subscriber1 + subscriber2; + } + + + static Observer getFirstObserver() { + return new Observer() { + + @Override + public void onNext(Integer value) { + subscriber1 += value; + System.out.println("Subscriber1: " + value); + } + + @Override + public void onError(Throwable e) { + System.out.println("error"); + } + + @Override + public void onCompleted() { + System.out.println("Subscriber1 completed"); + } + }; + } + + static Observer getSecondObserver() { + return new Observer() { + + @Override + public void onNext(Integer value) { + subscriber2 += value; + System.out.println("Subscriber2: " + value); + } + + @Override + public void onError(Throwable e) { + System.out.println("error"); + } + + @Override + public void onCompleted() { + System.out.println("Subscriber2 completed"); + } + }; + } + + public static void main(String[] args) throws InterruptedException { + System.out.println(subjectMethod()); + } +} diff --git a/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Connector.java b/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Connector.java new file mode 100644 index 0000000000..25cd0bde83 --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Connector.java @@ -0,0 +1,13 @@ +package com.baeldung.rxjava.jdbc; + +import com.github.davidmoten.rx.jdbc.ConnectionProvider; +import com.github.davidmoten.rx.jdbc.ConnectionProviderFromUrl; + +class Connector { + + private static final String DB_CONNECTION = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"; + private static final String DB_USER = ""; + private static final String DB_PASSWORD = ""; + + static final ConnectionProvider connectionProvider = new ConnectionProviderFromUrl(DB_CONNECTION, DB_USER, DB_PASSWORD); +} diff --git a/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Employee.java b/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Employee.java new file mode 100644 index 0000000000..790dddeb74 --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Employee.java @@ -0,0 +1,13 @@ +package com.baeldung.rxjava.jdbc; + +import com.github.davidmoten.rx.jdbc.annotations.Column; + +public interface Employee { + + @Column("id") + int id(); + + @Column("name") + String name(); + +} diff --git a/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Manager.java b/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Manager.java new file mode 100644 index 0000000000..56faa4cae7 --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Manager.java @@ -0,0 +1,28 @@ +package com.baeldung.rxjava.jdbc; + +public class Manager { + + private int id; + private String name; + + public Manager(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Utils.java b/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Utils.java new file mode 100644 index 0000000000..401962d1a9 --- /dev/null +++ b/rxjava/src/main/java/com/baeldung/rxjava/jdbc/Utils.java @@ -0,0 +1,16 @@ +package com.baeldung.rxjava.jdbc; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; + +import org.apache.commons.io.IOUtils; + +class Utils { + + static String getStringFromInputStream(InputStream input) throws IOException { + StringWriter writer = new StringWriter(); + IOUtils.copy(input, writer, "UTF-8"); + return writer.toString(); + } +} diff --git a/rxjava/src/main/java/com/baelding/rxjava/operator/ToCleanString.java b/rxjava/src/main/java/com/baeldung/rxjava/operator/ToCleanString.java similarity index 96% rename from rxjava/src/main/java/com/baelding/rxjava/operator/ToCleanString.java rename to rxjava/src/main/java/com/baeldung/rxjava/operator/ToCleanString.java index f6cf9fba68..708f7e9b86 100644 --- a/rxjava/src/main/java/com/baelding/rxjava/operator/ToCleanString.java +++ b/rxjava/src/main/java/com/baeldung/rxjava/operator/ToCleanString.java @@ -1,4 +1,4 @@ -package com.baelding.rxjava.operator; +package com.baeldung.rxjava.operator; import rx.Observable.Operator; import rx.Subscriber; @@ -39,5 +39,4 @@ public class ToCleanString implements Operator { } }; } - } \ No newline at end of file diff --git a/rxjava/src/main/java/com/baelding/rxjava/operator/ToLength.java b/rxjava/src/main/java/com/baeldung/rxjava/operator/ToLength.java similarity index 90% rename from rxjava/src/main/java/com/baelding/rxjava/operator/ToLength.java rename to rxjava/src/main/java/com/baeldung/rxjava/operator/ToLength.java index 006d59de36..70ba8b8ca9 100644 --- a/rxjava/src/main/java/com/baelding/rxjava/operator/ToLength.java +++ b/rxjava/src/main/java/com/baeldung/rxjava/operator/ToLength.java @@ -1,4 +1,4 @@ -package com.baelding.rxjava.operator; +package com.baeldung.rxjava.operator; import rx.Observable; import rx.Observable.Transformer; diff --git a/rxjava/src/test/java/com/baeldung/rxjava/ConnectableObservableTest.java b/rxjava/src/test/java/com/baeldung/rxjava/ConnectableObservableTest.java new file mode 100644 index 0000000000..031ff0c5bb --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/ConnectableObservableTest.java @@ -0,0 +1,27 @@ +package com.baeldung.rxjava; + +import org.junit.Test; +import rx.Observable; +import rx.observables.ConnectableObservable; + +import java.util.concurrent.TimeUnit; + +import static com.jayway.awaitility.Awaitility.await; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; + +public class ConnectableObservableTest { + + @Test + public void givenConnectableObservable_whenConnect_thenGetMessage() throws InterruptedException { + String[] result = {""}; + ConnectableObservable connectable + = Observable.interval(500, TimeUnit.MILLISECONDS).publish(); + connectable.subscribe(i -> result[0] += i); + assertFalse(result[0].equals("01")); + + connectable.connect(); + await() + .until(() -> assertTrue(result[0].equals("01"))); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/ObservableTest.java b/rxjava/src/test/java/com/baeldung/rxjava/ObservableTest.java new file mode 100644 index 0000000000..beb2cbeed3 --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/ObservableTest.java @@ -0,0 +1,144 @@ +package com.baeldung.rxjava; + +import org.junit.Test; +import rx.Observable; + +import static com.baeldung.rxjava.ObservableImpl.getTitle; +import static junit.framework.Assert.assertTrue; + +public class ObservableTest { + + private String result = ""; + + @Test + public void givenString_whenJustAndSubscribe_thenEmitsSingleItem() { + Observable observable = Observable.just("Hello"); + observable.subscribe(s -> result = s); + assertTrue(result.equals("Hello")); + } + + @Test + public void givenArray_whenFromAndSubscribe_thenEmitsItems() { + String[] letters = {"a", "b", "c", "d", "e", "f", "g"}; + Observable observable = Observable.from(letters); + observable.subscribe( + i -> result += i, + Throwable::printStackTrace, + () -> result += "_Complete" + ); + assertTrue(result.equals("abcdefg_Complete")); + } + + @Test + public void givenArray_whenConvertsObservabletoBlockingObservable_thenReturnFirstElement() { + String[] letters = {"a", "b", "c", "d", "e", "f", "g"}; + Observable observable = Observable.from(letters); + String blockingObservable = observable.toBlocking().first(); + + observable.subscribe( + i -> result += i, + Throwable::printStackTrace, + () -> result += "_Completed" + ); + assertTrue(String.valueOf(result.charAt(0)).equals(blockingObservable)); + } + + @Test + public void givenArray_whenMapAndSubscribe_thenReturnCapitalLetters() { + String[] letters = {"a", "b", "c", "d", "e", "f", "g"}; + + Observable.from(letters) + .map(String::toUpperCase) + .subscribe(letter -> result += letter); + + assertTrue(result.equals("ABCDEFG")); + } + + @Test + public void givenArray_whenFlatMapAndSubscribe_thenReturnUpperAndLowerCaseLetters() { + + Observable.just("book1", "book2") + .flatMap(s -> getTitle()) + .subscribe(l -> result += l); + + assertTrue(result.equals("titletitle")); + } + + @Test + public void givenArray_whenScanAndSubscribe_thenReturnTheSumOfAllLetters() { + String[] letters = {"a", "b", "c"}; + + Observable.from(letters) + .scan(new StringBuilder(), StringBuilder::append) + .subscribe(total -> result += total.toString()); + + assertTrue(result.equals("aababc")); + } + + @Test + public void givenArrayOfNumbers_whenGroupBy_thenCreateTwoGroupsBasedOnParity() { + Integer[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + String[] EVEN = {""}; + String[] ODD = {""}; + + Observable.from(numbers) + .groupBy(i -> 0 == (i % 2) ? "EVEN" : "ODD") + .subscribe(group -> + group.subscribe((number) -> { + if (group.getKey().equals("EVEN")) { + EVEN[0] += number; + } else { + ODD[0] += number; + } + }) + ); + + assertTrue(EVEN[0].equals("0246810")); + assertTrue(ODD[0].equals("13579")); + } + + @Test + public void givenArrayOfNumbers_whenFilter_thenGetAllOddNumbers() { + Integer[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + + Observable.from(numbers) + .filter(i -> (i % 2 == 1)) + .subscribe(i -> result += i); + + assertTrue(result.equals("13579")); + } + + @Test + public void givenEmptyObservable_whenDefaultIfEmpty_thenGetDefaultMessage() { + + Observable.empty() + .defaultIfEmpty("Observable is empty") + .subscribe(s -> result += s); + + assertTrue(result.equals("Observable is empty")); + } + + @Test + public void givenObservableFromArray_whenDefaultIfEmptyAndFirst_thenGetFirstLetterFromArray() { + String[] letters = {"a", "b", "c", "d", "e", "f", "g"}; + + Observable.from(letters) + .defaultIfEmpty("Observable is empty") + .first() + .subscribe(s -> result += s); + + assertTrue(result.equals("a")); + } + + @Test + public void givenObservableFromArray_whenTakeWhile_thenGetSumOfNumbersFromCondition() { + Integer[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + final Integer[] sum = {0}; + + Observable.from(numbers) + .takeWhile(i -> i < 5) + .subscribe(s -> sum[0] += s); + + assertTrue(sum[0] == 10); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/ResourceManagementTest.java b/rxjava/src/test/java/com/baeldung/rxjava/ResourceManagementTest.java new file mode 100644 index 0000000000..81be84fd0d --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/ResourceManagementTest.java @@ -0,0 +1,30 @@ +package com.baeldung.rxjava; + +import org.junit.Test; +import rx.Observable; + +import static junit.framework.Assert.assertTrue; + +public class ResourceManagementTest { + + @Test + public void givenResource_whenUsingOberservable_thenCreatePrintDisposeResource() throws InterruptedException { + + String[] result = {""}; + Observable values = Observable.using( + () -> "MyResource", + r -> Observable.create(o -> { + for (Character c : r.toCharArray()) + o.onNext(c); + o.onCompleted(); + }), + r -> System.out.println("Disposed: " + r) + ); + + values.subscribe( + v -> result[0] += v, + e -> result[0] += e + ); + assertTrue(result[0].equals("MyResource")); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaBackpressureLongRunningUnitTest.java b/rxjava/src/test/java/com/baeldung/rxjava/RxJavaBackpressureLongRunningUnitTest.java index 458091fd1c..e9dbb48b92 100644 --- a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaBackpressureLongRunningUnitTest.java +++ b/rxjava/src/test/java/com/baeldung/rxjava/RxJavaBackpressureLongRunningUnitTest.java @@ -27,7 +27,6 @@ public class RxJavaBackpressureLongRunningUnitTest { // then testSubscriber.awaitTerminalEvent(); assertTrue(testSubscriber.getOnErrorEvents().size() == 0); - } @Test @@ -60,7 +59,6 @@ public class RxJavaBackpressureLongRunningUnitTest { // then testSubscriber.awaitTerminalEvent(2, TimeUnit.SECONDS); assertTrue(testSubscriber.getOnErrorEvents().size() == 0); - } @Test @@ -77,7 +75,6 @@ public class RxJavaBackpressureLongRunningUnitTest { // then testSubscriber.awaitTerminalEvent(2, TimeUnit.SECONDS); assertTrue(testSubscriber.getOnErrorEvents().size() == 0); - } @Test @@ -88,15 +85,14 @@ public class RxJavaBackpressureLongRunningUnitTest { // when source.sample(100, TimeUnit.MILLISECONDS) - // .throttleFirst(100, TimeUnit.MILLISECONDS) - .observeOn(Schedulers.computation()).subscribe(testSubscriber); + // .throttleFirst(100, TimeUnit.MILLISECONDS) + .observeOn(Schedulers.computation()).subscribe(testSubscriber); IntStream.range(0, 1_000).forEach(source::onNext); // then testSubscriber.awaitTerminalEvent(2, TimeUnit.SECONDS); assertTrue(testSubscriber.getOnErrorEvents().size() == 0); - } @Test @@ -111,7 +107,6 @@ public class RxJavaBackpressureLongRunningUnitTest { // then testSubscriber.awaitTerminalEvent(2, TimeUnit.SECONDS); assertTrue(testSubscriber.getOnErrorEvents().size() == 0); - } @Test @@ -120,11 +115,11 @@ public class RxJavaBackpressureLongRunningUnitTest { TestSubscriber testSubscriber = new TestSubscriber<>(); // when - Observable.range(1, 1_000_000).onBackpressureDrop().observeOn(Schedulers.computation()).subscribe(testSubscriber); + Observable.range(1, 1_000_000).onBackpressureDrop().observeOn(Schedulers.computation()) + .subscribe(testSubscriber); // then testSubscriber.awaitTerminalEvent(2, TimeUnit.SECONDS); assertTrue(testSubscriber.getOnErrorEvents().size() == 0); - } } diff --git a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaCustomOperatorUnitTest.java b/rxjava/src/test/java/com/baeldung/rxjava/RxJavaCustomOperatorUnitTest.java index a49103196c..414d951b86 100644 --- a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaCustomOperatorUnitTest.java +++ b/rxjava/src/test/java/com/baeldung/rxjava/RxJavaCustomOperatorUnitTest.java @@ -1,25 +1,21 @@ package com.baeldung.rxjava; -import static com.baelding.rxjava.operator.ToCleanString.toCleanString; -import static com.baelding.rxjava.operator.ToLength.toLength; -import static org.hamcrest.Matchers.hasItems; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import org.junit.Test; - import rx.Observable; import rx.Observable.Operator; import rx.Observable.Transformer; import rx.Subscriber; -import com.baelding.rxjava.operator.ToCleanString; -import com.baelding.rxjava.operator.ToLength; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static com.baeldung.rxjava.operator.ToCleanString.toCleanString; +import static com.baeldung.rxjava.operator.ToLength.toLength; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; public class RxJavaCustomOperatorUnitTest { @@ -29,7 +25,7 @@ public class RxJavaCustomOperatorUnitTest { final List results = new ArrayList<>(); final Observable observable = Observable.from(list) - .lift(toCleanString()); + .lift(toCleanString()); // when observable.subscribe(results::add); @@ -46,7 +42,7 @@ public class RxJavaCustomOperatorUnitTest { final List results = new ArrayList<>(); final Observable observable = Observable.from(list) - .compose(toLength()); + .compose(toLength()); // when observable.subscribe(results::add); @@ -85,8 +81,8 @@ public class RxJavaCustomOperatorUnitTest { final List results = new ArrayList<>(); Observable.from(Arrays.asList("ap_p-l@e", "or-an?ge")) - .lift(cleanStringFn) - .subscribe(results::add); + .lift(cleanStringFn) + .subscribe(results::add); assertThat(results, notNullValue()); assertThat(results, hasSize(2)); @@ -99,8 +95,8 @@ public class RxJavaCustomOperatorUnitTest { final List results = new ArrayList<>(); Observable.from(Arrays.asList("apple", "orange")) - .compose(toLengthFn) - .subscribe(results::add); + .compose(toLengthFn) + .subscribe(results::add); assertThat(results, notNullValue()); assertThat(results, hasSize(2)); diff --git a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaUnitTest.java b/rxjava/src/test/java/com/baeldung/rxjava/RxJavaUnitTest.java index 1e59b8c2d9..31ec473dc6 100644 --- a/rxjava/src/test/java/com/baeldung/rxjava/RxJavaUnitTest.java +++ b/rxjava/src/test/java/com/baeldung/rxjava/RxJavaUnitTest.java @@ -10,7 +10,9 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThat; public class RxJavaUnitTest { @@ -19,7 +21,8 @@ public class RxJavaUnitTest { // given List letters = Arrays.asList("A", "B", "C", "D", "E"); List results = new ArrayList<>(); - Observable observable = Observable.from(letters).zipWith(Observable.range(1, Integer.MAX_VALUE), (string, index) -> index + "-" + string); + Observable observable = Observable.from(letters) + .zipWith(Observable.range(1, Integer.MAX_VALUE), (string, index) -> index + "-" + string); // when observable.subscribe(results::add); @@ -36,7 +39,8 @@ public class RxJavaUnitTest { List letters = Arrays.asList("A", "B", "C", "D", "E"); TestSubscriber subscriber = new TestSubscriber<>(); - Observable observable = Observable.from(letters).zipWith(Observable.range(1, Integer.MAX_VALUE), ((string, index) -> index + "-" + string)); + Observable observable = Observable.from(letters) + .zipWith(Observable.range(1, Integer.MAX_VALUE), ((string, index) -> index + "-" + string)); // when observable.subscribe(subscriber); @@ -54,7 +58,9 @@ public class RxJavaUnitTest { List letters = Arrays.asList("A", "B", "C", "D", "E"); TestSubscriber subscriber = new TestSubscriber<>(); - Observable observable = Observable.from(letters).zipWith(Observable.range(1, Integer.MAX_VALUE), ((string, index) -> index + "-" + string)).concatWith(Observable.error(new RuntimeException("error in Observable"))); + Observable observable = Observable.from(letters) + .zipWith(Observable.range(1, Integer.MAX_VALUE), ((string, index) -> index + "-" + string)) + .concatWith(Observable.error(new RuntimeException("error in Observable"))); // when observable.subscribe(subscriber); diff --git a/rxjava/src/test/java/com/baeldung/rxjava/SchedulersLiveTest.java b/rxjava/src/test/java/com/baeldung/rxjava/SchedulersLiveTest.java new file mode 100644 index 0000000000..712f07324c --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/SchedulersLiveTest.java @@ -0,0 +1,246 @@ +package com.baeldung.rxjava; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import org.junit.Ignore; +import org.junit.Test; +import rx.Observable; +import rx.Scheduler; +import rx.observers.TestSubscriber; +import rx.schedulers.Schedulers; +import rx.schedulers.TestScheduler; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +import static com.jayway.awaitility.Awaitility.await; +import static java.util.concurrent.Executors.newFixedThreadPool; +import static org.hamcrest.Matchers.hasItems; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class SchedulersLiveTest { + private String result = ""; + private String result1 = ""; + private String result2 = ""; + + @Test + public void givenScheduledWorker_whenScheduleAnAction_thenResultAction() throws InterruptedException { + System.out.println("scheduling"); + Scheduler scheduler = Schedulers.immediate(); + Scheduler.Worker worker = scheduler.createWorker(); + worker.schedule(() -> result += "action"); + + assertTrue(result.equals("action")); + } + + @Test + public void givenScheduledWorker_whenUnsubscribeOnWorker_thenResultFirstAction() throws InterruptedException { + System.out.println("canceling"); + Scheduler scheduler = Schedulers.newThread(); + Scheduler.Worker worker = scheduler.createWorker(); + worker.schedule(() -> { + result += "First_Action"; + worker.unsubscribe(); + }); + worker.schedule(() -> result += "Second_Action"); + + await() + .until(() -> assertTrue(result.equals("First_Action"))); + } + + @Ignore //it's not safe, not every time is running correctly + @Test + public void givenWorker_whenScheduledOnNewThread_thenResultIsBoundToNewThread() throws InterruptedException { + System.out.println("newThread_1"); + Scheduler scheduler = Schedulers.newThread(); + Scheduler.Worker worker = scheduler.createWorker(); + worker.schedule(() -> { + result += Thread.currentThread().getName() + "_Start"; + worker.schedule(() -> result += "_worker_"); + result += "_End"; + }); + + await() + .until(() -> assertTrue(result.equals("RxNewThreadScheduler-1_Start_End_worker_"))); + } + + @Test + public void givenObservable_whenObserveOnNewThread_thenRunOnDifferentThreadEachTime() throws InterruptedException { + System.out.println("newThread_2"); + Observable.just("Hello") + .observeOn(Schedulers.newThread()) + .doOnNext(s -> + result2 += Thread.currentThread().getName() + ) + .observeOn(Schedulers.newThread()) + .subscribe(s -> + result1 += Thread.currentThread().getName() + ); + await() + .until(() -> { + assertTrue(result1.equals("RxNewThreadScheduler-1")); + assertTrue(result2.equals("RxNewThreadScheduler-2")); + }); + } + + @Test + public void givenWorker_whenScheduledOnImmediate_thenResultIsBoundToThread() throws InterruptedException { + System.out.println("immediate_1"); + Scheduler scheduler = Schedulers.immediate(); + Scheduler.Worker worker = scheduler.createWorker(); + worker.schedule(() -> { + result += Thread.currentThread().getName() + "_Start"; + worker.schedule(() -> result += "_worker_"); + result += "_End"; + }); + + await() + .until(() -> assertTrue(result.equals("main_Start_worker__End"))); + } + + @Test + public void givenObservable_whenImmediateScheduled_thenExecuteOnMainThread() throws InterruptedException { + System.out.println("immediate_2"); + Observable.just("Hello") + .subscribeOn(Schedulers.immediate()) + .subscribe(s -> + result += Thread.currentThread().getName() + ); + + await() + .until(() -> assertTrue(result.equals("main"))); + } + + @Test + public void givenObservable_whenTrampolineScheduled_thenExecuteOnMainThread() throws InterruptedException { + System.out.println("trampoline_1"); + Observable.just(2, 4, 6, 8) + .subscribeOn(Schedulers.trampoline()) + .subscribe(i -> result += "" + i); + Observable.just(1, 3, 5, 7, 9) + .subscribeOn(Schedulers.trampoline()) + .subscribe(i -> result += "" + i); + + await() + .until(() -> assertTrue(result.equals("246813579"))); + } + + @Test + public void givenWorker_whenScheduledOnTrampoline_thenComposeResultAsBlocking() throws InterruptedException { + System.out.println("trampoline_2"); + Scheduler scheduler = Schedulers.trampoline(); + Scheduler.Worker worker = scheduler.createWorker(); + worker.schedule(() -> { + result += Thread.currentThread().getName() + "Start"; + worker.schedule(() -> { + result += "_middleStart"; + worker.schedule(() -> + result += "_worker_" + ); + result += "_middleEnd"; + }); + result += "_mainEnd"; + }); + + await() + .until(() -> assertTrue(result.equals("mainStart_mainEnd_middleStart_middleEnd_worker_"))); + } + + private ThreadFactory threadFactory(String pattern) { + return new ThreadFactoryBuilder() + .setNameFormat(pattern) + .build(); + } + + @Test + public void givenExecutors_whenSchedulerFromCreatedExecutors_thenReturnElementsOnEacheThread() throws InterruptedException { + System.out.println("from"); + ExecutorService poolA = newFixedThreadPool(10, threadFactory("Sched-A-%d")); + Scheduler schedulerA = Schedulers.from(poolA); + ExecutorService poolB = newFixedThreadPool(10, threadFactory("Sched-B-%d")); + Scheduler schedulerB = Schedulers.from(poolB); + + Observable observable = Observable.create(subscriber -> { + subscriber.onNext("Alfa"); + subscriber.onNext("Beta"); + subscriber.onCompleted(); + }); + + observable + .subscribeOn(schedulerA) + .subscribeOn(schedulerB) + .subscribe( + x -> result += Thread.currentThread().getName() + x + "_", + Throwable::printStackTrace, + () -> result += "_Completed" + ); + + await() + .until(() -> assertTrue(result.equals("Sched-A-0Alfa_Sched-A-0Beta__Completed"))); + } + + @Test + public void givenObservable_whenIoScheduling_thenReturnThreadName() throws InterruptedException { + System.out.println("io"); + Observable.just("io") + .subscribeOn(Schedulers.io()) + .subscribe(i -> result += Thread.currentThread().getName()); + + await() + .until(() -> assertTrue(result.equals("RxIoScheduler-2"))); + } + + @Test + public void givenObservable_whenComputationScheduling_thenReturnThreadName() throws InterruptedException { + System.out.println("computation"); + Observable.just("computation") + .subscribeOn(Schedulers.computation()) + .subscribe(i -> result += Thread.currentThread().getName()); + + await() + .until(() -> assertTrue(result.equals("RxComputationScheduler-1"))); + } + + @Test + public void givenLetters_whenTestScheduling_thenReturnValuesControllingAdvanceTime() throws InterruptedException { + List letters = Arrays.asList("A", "B", "C"); + TestScheduler scheduler = Schedulers.test(); + TestSubscriber subscriber = new TestSubscriber<>(); + + Observable tick = Observable.interval(1, TimeUnit.SECONDS, scheduler); + + Observable.from(letters) + .zipWith(tick, (string, index) -> index + "-" + string) + .subscribeOn(scheduler) + .subscribe(subscriber); + + subscriber.assertNoValues(); + subscriber.assertNotCompleted(); + + scheduler.advanceTimeBy(1, TimeUnit.SECONDS); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValues("0-A"); + + scheduler.advanceTimeTo(3, TimeUnit.SECONDS); + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(3); + assertThat(subscriber.getOnNextEvents(), hasItems("0-A", "1-B", "2-C")); + } + + @Test + public void givenLetters_whenDelay_thenReturne() throws InterruptedException { + ExecutorService poolA = newFixedThreadPool(10, threadFactory("Sched1-")); + Scheduler schedulerA = Schedulers.from(poolA); + Observable.just('A', 'B') + .delay(1, TimeUnit.SECONDS, schedulerA) + .subscribe(i -> result += Thread.currentThread().getName() + i + " "); + + await() + .until(() -> assertTrue(result.equals("Sched1-A Sched1-B "))); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/SingleTest.java b/rxjava/src/test/java/com/baeldung/rxjava/SingleTest.java new file mode 100644 index 0000000000..1352841ed9 --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/SingleTest.java @@ -0,0 +1,23 @@ +package com.baeldung.rxjava; + +import org.junit.Test; +import rx.Observable; +import rx.Single; + +import static junit.framework.Assert.assertTrue; + +public class SingleTest { + + @Test + public void givenSingleObservable_whenSuccess_thenGetMessage() throws InterruptedException { + String[] result = {""}; + Single single = Observable.just("Hello") + .toSingle() + .doOnSuccess(i -> result[0] += i) + .doOnError(error -> { + throw new RuntimeException(error.getMessage()); + }); + single.subscribe(); + assertTrue(result[0].equals("Hello")); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/SubjectTest.java b/rxjava/src/test/java/com/baeldung/rxjava/SubjectTest.java new file mode 100644 index 0000000000..628b1e5476 --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/SubjectTest.java @@ -0,0 +1,25 @@ +package com.baeldung.rxjava; + +import org.junit.Test; +import rx.subjects.PublishSubject; + +import static junit.framework.Assert.assertTrue; + +public class SubjectTest { + + @Test + public void givenSubjectAndTwoSubscribers_whenSubscribeOnSubject_thenSubscriberBeginsToAdd() { + PublishSubject subject = PublishSubject.create(); + + subject.subscribe(SubjectImpl.getFirstObserver()); + subject.onNext(1); + subject.onNext(2); + subject.onNext(3); + + subject.subscribe(SubjectImpl.getSecondObserver()); + subject.onNext(4); + subject.onCompleted(); + + assertTrue(SubjectImpl.subscriber1 + SubjectImpl.subscriber2 == 14); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/UtilityOperatorsTest.java b/rxjava/src/test/java/com/baeldung/rxjava/UtilityOperatorsTest.java new file mode 100644 index 0000000000..0b38f0387b --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/UtilityOperatorsTest.java @@ -0,0 +1,270 @@ +package com.baeldung.rxjava; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import rx.Observable; +import rx.Observer; +import rx.exceptions.OnErrorNotImplementedException; +import rx.schedulers.Schedulers; +import rx.schedulers.Timestamped; + +import java.util.concurrent.TimeUnit; + +import static com.jayway.awaitility.Awaitility.await; +import static org.junit.Assert.assertTrue; + +public class UtilityOperatorsTest { + + private int emittedTotal = 0; + private int receivedTotal = 0; + private String result = ""; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void givenObservable_whenObserveOnAfterOnNext_thenEmitsEventsOnComputeScheduler() throws InterruptedException { + + Observable.range(1, 5) + .map(i -> i * 100) + .doOnNext(i -> { + emittedTotal += i; + System.out.println("Emitting " + i + + " on thread " + Thread.currentThread().getName()); + }) + .observeOn(Schedulers.computation()) + .map(i -> i * 10) + .subscribe(i -> { + receivedTotal += i; + System.out.println("Received " + i + " on thread " + + Thread.currentThread().getName()); + }); + + await().until(() -> { + assertTrue(emittedTotal == 1500); + assertTrue(receivedTotal == 15000); + } + ); + } + + @Test + public void givenObservable_whenObserveOnBeforeOnNext_thenEmitsEventsOnComputeScheduler() throws InterruptedException { + + Observable.range(1, 5) + .map(i -> i * 100) + .observeOn(Schedulers.computation()) + .doOnNext(i -> { + emittedTotal += i; + System.out.println("Emitting " + i + + " on thread " + Thread.currentThread().getName()); + }) + .map(i -> i * 10) + .subscribe(i -> { + receivedTotal += i; + System.out.println("Received " + i + " on thread " + + Thread.currentThread().getName()); + }); + + await().until(() -> { + assertTrue(emittedTotal == 1500); + assertTrue(receivedTotal == 15000); + }); + } + + @Test + public void givenObservable_whenSubscribeOn_thenEmitsEventsOnComputeScheduler() throws InterruptedException { + + Observable.range(1, 5) + .map(i -> i * 100) + .doOnNext(i -> { + emittedTotal += i; + System.out.println("Emitting " + i + + " on thread " + Thread.currentThread().getName()); + }) + .subscribeOn(Schedulers.computation()) + .map(i -> i * 10) + .subscribe(i -> { + receivedTotal += i; + System.out.println("Received " + i + " on thread " + + Thread.currentThread().getName()); + }); + + await().until(() -> { + assertTrue(emittedTotal == 1500); + assertTrue(receivedTotal == 15000); + }); + } + + @Test + public void givenObservableWithOneEvent_whenSingle_thenEmitEvent() { + + Observable.range(1, 1) + .single() + .subscribe(i -> receivedTotal += i); + assertTrue(receivedTotal == 1); + } + + @Test + public void givenObservableWithNoEvents_whenSingle_thenThrowException() { + + Observable.range(1, 3) + .single() + .onErrorReturn(e -> receivedTotal += 10) + .subscribe(); + assertTrue(receivedTotal == 10); + } + + @Test + public void givenObservableWihNoEvents_whenSingleOrDefault_thenDefaultMessage() { + + Observable.empty() + .singleOrDefault("Default") + .subscribe(i -> result += i); + assertTrue(result.equals("Default")); + } + + @Test + public void givenObservableWithManyEvents_whenSingleOrDefault_thenThrowException() { + + Observable.range(1, 3) + .singleOrDefault(5) + .onErrorReturn(e -> receivedTotal += 10) + .subscribe(); + assertTrue(receivedTotal == 10); + } + + @Test + public void givenObservable_whenDoOnNextAndDoOnCompleted_thenSumAllEventsAndShowMessage() { + + Observable.range(1, 10) + .doOnNext(r -> receivedTotal += r) + .doOnCompleted(() -> result = "Completed") + .subscribe(); + assertTrue(receivedTotal == 55); + assertTrue(result.equals("Completed")); + } + + @Test + public void givenObservable_whenDoOnEachAndDoOnSubscribe_thenSumAllValuesAndShowMessage() { + + Observable.range(1, 10) + .doOnEach(new Observer() { + @Override + public void onCompleted() { + System.out.println("Complete"); + } + + @Override + public void onError(Throwable e) { + e.printStackTrace(); + } + + @Override + public void onNext(Integer value) { + receivedTotal += value; + } + }) + .doOnSubscribe(() -> result = "Subscribed") + .subscribe(); + assertTrue(receivedTotal == 55); + assertTrue(result.equals("Subscribed")); + } + + @Test + public void givenObservable_whenDoOnErrorDoOnTerminateAndDoAfterTerminate_thenShowErrorTerminateAndAfterTerminateMessages() { + + thrown.expect(OnErrorNotImplementedException.class); + Observable.empty() + .single() + .doOnError(throwable -> { + throw new RuntimeException("error"); + }) + .doOnTerminate(() -> result += "doOnTerminate") + .doAfterTerminate(() -> result += "_doAfterTerminate") + .subscribe(); + assertTrue(result.equals("doOnTerminate_doAfterTerminate")); + } + + @Test + public void givenObservable_whenTimestamp_thenEventsShouldAppearTimestamped() { + + Observable.range(1, 10) + .timestamp() + .map(o -> result = o.getClass().toString()) + .last() + .subscribe(); + assertTrue(result.equals("class rx.schedulers.Timestamped")); + } + + @Test + public void givenObservables_whenDelay_thenEventsStartAppearAfterATime() throws InterruptedException { + + Observable> source = Observable.interval(1, TimeUnit.SECONDS) + .take(5) + .timestamp(); + + Observable> delay = source.delaySubscription(2, TimeUnit.SECONDS); + + source.subscribe( + value -> System.out.println("source :" + value), + t -> System.out.println("source error"), + () -> System.out.println("source completed")); + + delay.subscribe( + value -> System.out.println("delay : " + value), + t -> System.out.println("delay error"), + () -> System.out.println("delay completed")); + //Thread.sleep(8000); + } + + @Test + public void givenObservable_whenRepeat_thenSumNumbersThreeTimes() { + + Observable.range(1, 3) + .repeat(3) + .subscribe(i -> receivedTotal += i); + assertTrue(receivedTotal == 18); + } + + @Test + public void givenObservable_whenUsing_thenReturnCreatedResource() { + + Observable values = Observable.using( + () -> "resource", + r -> Observable.create(o -> { + for (Character c : r.toCharArray()) { + o.onNext(c); + } + o.onCompleted(); + }), + r -> System.out.println("Disposed: " + r) + ); + values.subscribe( + v -> result += v, + e -> result += e + ); + assertTrue(result.equals("resource")); + } + + @Test + public void givenObservableCached_whenSubscribesWith2Actions_thenEmitsCachedValues() { + + Observable source = + Observable.create(subscriber -> { + System.out.println("Create"); + subscriber.onNext(receivedTotal += 5); + subscriber.onCompleted(); + } + ).cache(); + source.subscribe(i -> { + System.out.println("element 1"); + receivedTotal += 1; + }); + source.subscribe(i -> { + System.out.println("element 2"); + receivedTotal += 2; + }); + assertTrue(receivedTotal == 8); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapClassIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapClassIntegrationTest.java new file mode 100644 index 0000000000..957b6a4543 --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapClassIntegrationTest.java @@ -0,0 +1,63 @@ +package com.baeldung.rxjava.jdbc; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.davidmoten.rx.jdbc.ConnectionProvider; +import com.github.davidmoten.rx.jdbc.Database; + +import rx.Observable; + +public class AutomapClassIntegrationTest { + + private ConnectionProvider connectionProvider = Connector.connectionProvider; + private Database db = Database.from(connectionProvider); + + private Observable create = null; + private Observable insert1, insert2 = null; + + @Before + public void setup() { + create = db.update("CREATE TABLE IF NOT EXISTS MANAGER(id int primary key, name varchar(255))") + .count(); + insert1 = db.update("INSERT INTO MANAGER(id, name) VALUES(1, 'Alan')") + .dependsOn(create) + .count(); + insert2 = db.update("INSERT INTO MANAGER(id, name) VALUES(2, 'Sarah')") + .dependsOn(create) + .count(); + } + + @Test + public void whenSelectManagersAndAutomap_thenCorrect() { + List managers = db.select("select id, name from MANAGER") + .dependsOn(create) + .dependsOn(insert1) + .dependsOn(insert2) + .autoMap(Manager.class) + .toList() + .toBlocking() + .single(); + + assertThat(managers.get(0) + .getId()).isEqualTo(1); + assertThat(managers.get(0) + .getName()).isEqualTo("Alan"); + assertThat(managers.get(1) + .getId()).isEqualTo(2); + assertThat(managers.get(1) + .getName()).isEqualTo("Sarah"); + } + + @After + public void close() { + db.update("DROP TABLE MANAGER") + .dependsOn(create); + connectionProvider.close(); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java new file mode 100644 index 0000000000..477a2a1cb8 --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/AutomapInterfaceIntegrationTest.java @@ -0,0 +1,63 @@ +package com.baeldung.rxjava.jdbc; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.davidmoten.rx.jdbc.ConnectionProvider; +import com.github.davidmoten.rx.jdbc.Database; + +import rx.Observable; + +public class AutomapInterfaceIntegrationTest { + + private ConnectionProvider connectionProvider = Connector.connectionProvider; + private Database db = Database.from(connectionProvider); + + private Observable create = null; + private Observable insert1, insert2 = null; + + @Before + public void setup() { + create = db.update("CREATE TABLE IF NOT EXISTS EMPLOYEE(id int primary key, name varchar(255))") + .count(); + insert1 = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(1, 'Alan')") + .dependsOn(create) + .count(); + insert2 = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(2, 'Sarah')") + .dependsOn(create) + .count(); + } + + @Test + public void whenSelectFromTableAndAutomap_thenCorrect() { + List employees = db.select("select id, name from EMPLOYEE") + .dependsOn(create) + .dependsOn(insert1) + .dependsOn(insert2) + .autoMap(Employee.class) + .toList() + .toBlocking() + .single(); + + assertThat(employees.get(0) + .id()).isEqualTo(1); + assertThat(employees.get(0) + .name()).isEqualTo("Alan"); + assertThat(employees.get(1) + .id()).isEqualTo(2); + assertThat(employees.get(1) + .name()).isEqualTo("Sarah"); + } + + @After + public void close() { + db.update("DROP TABLE EMPLOYEE") + .dependsOn(create); + connectionProvider.close(); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java new file mode 100644 index 0000000000..5f445234d7 --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/BasicQueryTypesIntegrationTest.java @@ -0,0 +1,64 @@ +package com.baeldung.rxjava.jdbc; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.junit.After; +import org.junit.Test; + +import com.github.davidmoten.rx.jdbc.ConnectionProvider; +import com.github.davidmoten.rx.jdbc.Database; + +import rx.Observable; + +public class BasicQueryTypesIntegrationTest { + + private ConnectionProvider connectionProvider = Connector.connectionProvider; + private Database db = Database.from(connectionProvider); + + private Observable create; + + @Test + public void whenCreateTableAndInsertRecords_thenCorrect() { + create = db.update("CREATE TABLE IF NOT EXISTS EMPLOYEE(id int primary key, name varchar(255))") + .count(); + Observable insert1 = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(1, 'John')") + .dependsOn(create) + .count(); + Observable update = db.update("UPDATE EMPLOYEE SET name = 'Alan' WHERE id = 1") + .dependsOn(create) + .count(); + Observable insert2 = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(2, 'Sarah')") + .dependsOn(create) + .count(); + Observable insert3 = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(3, 'Mike')") + .dependsOn(create) + .count(); + Observable delete = db.update("DELETE FROM EMPLOYEE WHERE id = 2") + .dependsOn(create) + .count(); + List names = db.select("select name from EMPLOYEE where id < ?") + .parameter(3) + .dependsOn(create) + .dependsOn(insert1) + .dependsOn(insert2) + .dependsOn(insert3) + .dependsOn(update) + .dependsOn(delete) + .getAs(String.class) + .toList() + .toBlocking() + .single(); + + assertEquals(Arrays.asList("Alan"), names); + } + + @After + public void close() { + db.update("DROP TABLE EMPLOYEE") + .dependsOn(create); + connectionProvider.close(); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertBlobIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertBlobIntegrationTest.java new file mode 100644 index 0000000000..71eeded21c --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertBlobIntegrationTest.java @@ -0,0 +1,65 @@ +package com.baeldung.rxjava.jdbc; + +import static org.junit.Assert.assertEquals; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.davidmoten.rx.jdbc.ConnectionProvider; +import com.github.davidmoten.rx.jdbc.Database; + +import rx.Observable; + +public class InsertBlobIntegrationTest { + + private ConnectionProvider connectionProvider = Connector.connectionProvider; + private Database db = Database.from(connectionProvider); + + private String expectedDocument = null; + private String actualDocument = null; + + private Observable create, insert = null; + + @Before + public void setup() throws IOException { + create = db.update("CREATE TABLE IF NOT EXISTS SERVERLOG (id int primary key, document BLOB)") + .count(); + + InputStream actualInputStream = new FileInputStream("src/test/resources/actual_clob"); + this.actualDocument = Utils.getStringFromInputStream(actualInputStream); + byte[] bytes = this.actualDocument.getBytes(StandardCharsets.UTF_8); + + InputStream expectedInputStream = new FileInputStream("src/test/resources/expected_clob"); + this.expectedDocument = Utils.getStringFromInputStream(expectedInputStream); + this.insert = db.update("insert into SERVERLOG(id,document) values(?,?)") + .parameter(1) + .parameter(Database.toSentinelIfNull(bytes)) + .dependsOn(create) + .count(); + } + + @Test + public void whenInsertBLOB_thenCorrect() throws IOException { + db.select("select document from SERVERLOG where id = 1") + .dependsOn(create) + .dependsOn(insert) + .getAs(String.class) + .toList() + .toBlocking() + .single(); + assertEquals(expectedDocument, actualDocument); + } + + @After + public void close() { + db.update("DROP TABLE SERVERLOG") + .dependsOn(create); + connectionProvider.close(); + } +} \ No newline at end of file diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java new file mode 100644 index 0000000000..189bca4adb --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/InsertClobIntegrationTest.java @@ -0,0 +1,63 @@ +package com.baeldung.rxjava.jdbc; + +import static org.junit.Assert.assertEquals; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.davidmoten.rx.jdbc.ConnectionProvider; +import com.github.davidmoten.rx.jdbc.Database; + +import rx.Observable; + +public class InsertClobIntegrationTest { + + private ConnectionProvider connectionProvider = Connector.connectionProvider; + private Database db = Database.from(connectionProvider); + + private String expectedDocument = null; + private String actualDocument = null; + + private Observable create, insert = null; + + @Before + public void setup() throws IOException { + create = db.update("CREATE TABLE IF NOT EXISTS SERVERLOG (id int primary key, document CLOB)") + .count(); + + InputStream actualInputStream = new FileInputStream("src/test/resources/actual_clob"); + this.actualDocument = Utils.getStringFromInputStream(actualInputStream); + + InputStream expectedInputStream = new FileInputStream("src/test/resources/expected_clob"); + this.expectedDocument = Utils.getStringFromInputStream(expectedInputStream); + this.insert = db.update("insert into SERVERLOG(id,document) values(?,?)") + .parameter(1) + .parameter(Database.toSentinelIfNull(actualDocument)) + .dependsOn(create) + .count(); + } + + @Test + public void whenSelectCLOB_thenCorrect() throws IOException { + db.select("select document from SERVERLOG where id = 1") + .dependsOn(create) + .dependsOn(insert) + .getAs(String.class) + .toList() + .toBlocking() + .single(); + assertEquals(expectedDocument, actualDocument); + } + + @After + public void close() { + db.update("DROP TABLE SERVERLOG") + .dependsOn(create); + connectionProvider.close(); + } +} \ No newline at end of file diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java new file mode 100644 index 0000000000..2018a9427c --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/ReturnKeysIntegrationTest.java @@ -0,0 +1,48 @@ +package com.baeldung.rxjava.jdbc; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.davidmoten.rx.jdbc.ConnectionProvider; +import com.github.davidmoten.rx.jdbc.Database; + +import rx.Observable; + +public class ReturnKeysIntegrationTest { + + private Observable begin = null; + private Observable createStatement = null; + + private ConnectionProvider connectionProvider = Connector.connectionProvider; + private Database db = Database.from(connectionProvider); + + @Before + public void setup() { + begin = db.beginTransaction(); + createStatement = db.update("CREATE TABLE IF NOT EXISTS EMPLOYEE(id int auto_increment primary key, name varchar(255))") + .dependsOn(begin) + .count(); + } + + @Test + public void whenInsertAndReturnGeneratedKey_thenCorrect() { + Integer key = db.update("INSERT INTO EMPLOYEE(name) VALUES('John')") + .dependsOn(createStatement) + .returnGeneratedKeys() + .getAs(Integer.class) + .count() + .toBlocking() + .single(); + assertThat(key).isEqualTo(1); + } + + @After + public void close() { + db.update("DROP TABLE EMPLOYEE") + .dependsOn(createStatement); + connectionProvider.close(); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java new file mode 100644 index 0000000000..4e24d7f10e --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/jdbc/TransactionIntegrationTest.java @@ -0,0 +1,49 @@ +package com.baeldung.rxjava.jdbc; + +import static org.junit.Assert.assertEquals; + +import org.junit.After; +import org.junit.Test; + +import com.github.davidmoten.rx.jdbc.ConnectionProvider; +import com.github.davidmoten.rx.jdbc.Database; + +import rx.Observable; + +public class TransactionIntegrationTest { + + private Observable createStatement = null; + + private ConnectionProvider connectionProvider = Connector.connectionProvider; + private Database db = Database.from(connectionProvider); + + @Test + public void whenCommitTransaction_thenRecordUpdated() { + Observable begin = db.beginTransaction(); + Observable createStatement = db + .update("CREATE TABLE IF NOT EXISTS EMPLOYEE(id int primary key, name varchar(255))") + .dependsOn(begin) + .count(); + Observable insertStatement = db.update("INSERT INTO EMPLOYEE(id, name) VALUES(1, 'John')") + .dependsOn(createStatement) + .count(); + Observable updateStatement = db.update("UPDATE EMPLOYEE SET name = 'Tom' WHERE id = 1") + .dependsOn(insertStatement) + .count(); + Observable commit = db.commit(updateStatement); + String name = db.select("select name from EMPLOYEE WHERE id = 1") + .dependsOn(commit) + .getAs(String.class) + .toBlocking() + .single(); + + assertEquals("Tom", name); + } + + @After + public void close() { + db.update("DROP TABLE EMPLOYEE") + .dependsOn(createStatement); + connectionProvider.close(); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingTest.java b/rxjava/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingTest.java new file mode 100644 index 0000000000..b1d711ab39 --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/onerror/ExceptionHandlingTest.java @@ -0,0 +1,138 @@ +package com.baeldung.rxjava.onerror; + +import io.reactivex.Observable; +import io.reactivex.exceptions.CompositeException; +import io.reactivex.observers.TestObserver; +import org.junit.Test; + +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.junit.Assert.assertTrue; + +public class ExceptionHandlingTest { + + private Error UNKNOWN_ERROR = new Error("unknown error"); + private Exception UNKNOWN_EXCEPTION = new Exception("unknown exception"); + + @Test + public void givenSubscriberAndError_whenHandleOnErrorReturn_thenResumed() { + TestObserver testObserver = new TestObserver<>(); + + Observable + .error(UNKNOWN_ERROR) + .onErrorReturn(Throwable::getMessage) + .subscribe(testObserver); + + testObserver.assertNoErrors(); + testObserver.assertComplete(); + testObserver.assertValueCount(1); + testObserver.assertValue("unknown error"); + } + + @Test + public void givenSubscriberAndError_whenHandleOnErrorResume_thenResumed() { + TestObserver testObserver = new TestObserver<>(); + + Observable + .error(UNKNOWN_ERROR) + .onErrorResumeNext(Observable.just("one", "two")) + .subscribe(testObserver); + + testObserver.assertNoErrors(); + testObserver.assertComplete(); + testObserver.assertValueCount(2); + testObserver.assertValues("one", "two"); + } + + @Test + public void givenSubscriberAndError_whenHandleOnErrorResumeItem_thenResumed() { + TestObserver testObserver = new TestObserver<>(); + + Observable + .error(UNKNOWN_ERROR) + .onErrorReturnItem("singleValue") + .subscribe(testObserver); + + testObserver.assertNoErrors(); + testObserver.assertComplete(); + testObserver.assertValueCount(1); + testObserver.assertValue("singleValue"); + } + + @Test + public void givenSubscriberAndError_whenHandleOnErrorResumeFunc_thenResumed() { + TestObserver testObserver = new TestObserver<>(); + + Observable + .error(UNKNOWN_ERROR) + .onErrorResumeNext(throwable -> { + return Observable.just(throwable.getMessage(), "nextValue"); + }) + .subscribe(testObserver); + + testObserver.assertNoErrors(); + testObserver.assertComplete(); + testObserver.assertValueCount(2); + testObserver.assertValues("unknown error", "nextValue"); + } + + @Test + public void givenSubscriberAndError_whenChangeStateOnError_thenErrorThrown() { + TestObserver testObserver = new TestObserver<>(); + final AtomicBoolean state = new AtomicBoolean(false); + + Observable + .error(UNKNOWN_ERROR) + .doOnError(throwable -> state.set(true)) + .subscribe(testObserver); + + testObserver.assertError(UNKNOWN_ERROR); + testObserver.assertNotComplete(); + testObserver.assertNoValues(); + assertTrue("state should be changed", state.get()); + } + + @Test + public void givenSubscriberAndError_whenExceptionOccurOnError_thenCompositeExceptionThrown() { + TestObserver testObserver = new TestObserver<>(); + + Observable + .error(UNKNOWN_ERROR) + .doOnError(throwable -> { + throw new RuntimeException("unexcepted"); + }) + .subscribe(testObserver); + + testObserver.assertError(CompositeException.class); + testObserver.assertNotComplete(); + testObserver.assertNoValues(); + } + + @Test + public void givenSubscriberAndException_whenHandleOnException_thenResumed() { + TestObserver testObserver = new TestObserver<>(); + + Observable + .error(UNKNOWN_EXCEPTION) + .onExceptionResumeNext(Observable.just("exceptionResumed")) + .subscribe(testObserver); + + testObserver.assertNoErrors(); + testObserver.assertComplete(); + testObserver.assertValueCount(1); + testObserver.assertValue("exceptionResumed"); + } + + @Test + public void givenSubscriberAndError_whenHandleOnException_thenNotResumed() { + TestObserver testObserver = new TestObserver<>(); + + Observable + .error(UNKNOWN_ERROR) + .onExceptionResumeNext(Observable.just("exceptionResumed")) + .subscribe(testObserver); + + testObserver.assertError(UNKNOWN_ERROR); + testObserver.assertNotComplete(); + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryTest.java b/rxjava/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryTest.java new file mode 100644 index 0000000000..3cc72056ba --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/onerror/OnErrorRetryTest.java @@ -0,0 +1,146 @@ +package com.baeldung.rxjava.onerror; + +import io.reactivex.Observable; +import io.reactivex.observers.TestObserver; +import org.junit.Test; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.Assert.assertTrue; + +public class OnErrorRetryTest { + + private Error UNKNOWN_ERROR = new Error("unknown error"); + + @Test + public void givenSubscriberAndError_whenRetryOnError_thenRetryConfirmed() { + TestObserver testObserver = new TestObserver<>(); + AtomicInteger atomicCounter = new AtomicInteger(0); + + Observable + .error(() -> { + atomicCounter.incrementAndGet(); + return UNKNOWN_ERROR; + }) + .retry(1) + .subscribe(testObserver); + + testObserver.assertError(UNKNOWN_ERROR); + testObserver.assertNotComplete(); + testObserver.assertNoValues(); + assertTrue("should call twice", atomicCounter.get() == 2); + } + + @Test + public void givenSubscriberAndError_whenRetryConditionallyOnError_thenRetryConfirmed() { + TestObserver testObserver = new TestObserver<>(); + + AtomicInteger atomicCounter = new AtomicInteger(0); + + Observable + .error(() -> { + atomicCounter.incrementAndGet(); + return UNKNOWN_ERROR; + }) + .retry((integer, throwable) -> integer < 4) + .subscribe(testObserver); + + testObserver.assertError(UNKNOWN_ERROR); + testObserver.assertNotComplete(); + testObserver.assertNoValues(); + assertTrue("should call 4 times", atomicCounter.get() == 4); + } + + @Test + public void givenSubscriberAndError_whenRetryUntilOnError_thenRetryConfirmed() { + TestObserver testObserver = new TestObserver<>(); + AtomicInteger atomicCounter = new AtomicInteger(0); + + Observable + .error(UNKNOWN_ERROR) + .retryUntil(() -> atomicCounter.incrementAndGet() > 3) + .subscribe(testObserver); + + testObserver.assertError(UNKNOWN_ERROR); + testObserver.assertNotComplete(); + testObserver.assertNoValues(); + assertTrue("should call 4 times", atomicCounter.get() == 4); + } + + @Test + public void givenSubscriberAndError_whenRetryWhenOnError_thenRetryConfirmed() { + TestObserver testObserver = new TestObserver<>(); + Exception noretryException = new Exception("don't retry"); + + Observable + .error(UNKNOWN_ERROR) + .retryWhen(throwableObservable -> Observable.error(noretryException)) + .subscribe(testObserver); + + testObserver.assertError(noretryException); + testObserver.assertNotComplete(); + testObserver.assertNoValues(); + } + + @Test + public void givenSubscriberAndError_whenRetryWhenOnError_thenCompleted() { + TestObserver testObserver = new TestObserver<>(); + AtomicInteger atomicCounter = new AtomicInteger(0); + + Observable + .error(() -> { + atomicCounter.incrementAndGet(); + return UNKNOWN_ERROR; + }) + .retryWhen(throwableObservable -> Observable.empty()) + .subscribe(testObserver); + + testObserver.assertNoErrors(); + testObserver.assertComplete(); + testObserver.assertNoValues(); + assertTrue("should not retry", atomicCounter.get() == 0); + } + + @Test + public void givenSubscriberAndError_whenRetryWhenOnError_thenResubscribed() { + TestObserver testObserver = new TestObserver<>(); + AtomicInteger atomicCounter = new AtomicInteger(0); + + Observable + .error(() -> { + atomicCounter.incrementAndGet(); + return UNKNOWN_ERROR; + }) + .retryWhen(throwableObservable -> Observable.just("anything")) + .subscribe(testObserver); + + testObserver.assertNoErrors(); + testObserver.assertComplete(); + testObserver.assertNoValues(); + assertTrue("should retry once", atomicCounter.get() == 1); + } + + @Test + public void givenSubscriberAndError_whenRetryWhenForMultipleTimesOnError_thenResumed() { + TestObserver testObserver = new TestObserver<>(); + long before = System.currentTimeMillis(); + + Observable + .error(UNKNOWN_ERROR) + .retryWhen(throwableObservable -> throwableObservable + .zipWith(Observable.range(1, 3), (throwable, integer) -> integer) + .flatMap(integer -> { + System.out.println("retried " + integer + " times"); + return Observable.timer(integer, TimeUnit.SECONDS); + })) + .blockingSubscribe(testObserver); + + testObserver.assertNoErrors(); + testObserver.assertComplete(); + testObserver.assertNoValues(); + long secondsElapsed = (System.currentTimeMillis() - before) / 1000; + assertTrue("6 seconds should elapse", secondsElapsed == 6); + } + +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/operators/RxAggregateOperatorsTest.java b/rxjava/src/test/java/com/baeldung/rxjava/operators/RxAggregateOperatorsTest.java new file mode 100644 index 0000000000..6733aa08c5 --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/operators/RxAggregateOperatorsTest.java @@ -0,0 +1,221 @@ +package com.baeldung.rxjava.operators; + +import org.junit.Test; +import rx.Observable; +import rx.observers.TestSubscriber; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +public class RxAggregateOperatorsTest { + + @Test + public void givenTwoObservable_whenConcatenatingThem_thenSuccessfull() { + // given + List listOne = Arrays.asList(1, 2, 3, 4); + Observable observableOne = Observable.from(listOne); + + List listTwo = Arrays.asList(5, 6, 7, 8); + Observable observableTwo = Observable.from(listTwo); + + TestSubscriber subscriber = TestSubscriber.create(); + + // when + Observable concatObservable = observableOne.concatWith(observableTwo); + + concatObservable.subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(8); + subscriber.assertValues(1, 2, 3, 4, 5, 6, 7, 8); + } + + @Test + public void givenObservable_whenCounting_thenObtainingNumberOfElements() { + // given + List lettersList = Arrays.asList("A", "B", "C", "D", "E", "F", "G"); + + TestSubscriber subscriber = TestSubscriber.create(); + + // when + Observable sourceObservable = Observable.from(lettersList) + .count(); + sourceObservable.subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(7); + } + + @Test + public void givenObservable_whenReducing_thenObtainingInvertedConcatenatedString() { + // given + List list = Arrays.asList("A", "B", "C", "D", "E", "F", "G"); + + TestSubscriber subscriber = TestSubscriber.create(); + + // when + Observable reduceObservable = Observable.from(list) + .reduce((letter1, letter2) -> letter2 + letter1); + reduceObservable.subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue("GFEDCBA"); + } + + @Test + public void givenObservable_whenCollecting_thenObtainingASet() { + // given + List list = Arrays.asList("A", "B", "C", "B", "B", "A", "D"); + + TestSubscriber subscriber = TestSubscriber.create(); + + // when + Observable> reduceListObservable = Observable.from(list) + .collect(HashSet::new, HashSet::add); + reduceListObservable.subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValues(new HashSet<>(list)); + } + + @Test + public void givenObservable_whenUsingToList_thenObtainedAList() { + // given + Observable sourceObservable = Observable.range(1, 5); + TestSubscriber subscriber = TestSubscriber.create(); + + // when + Observable> listObservable = sourceObservable.toList(); + listObservable.subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(Arrays.asList(1, 2, 3, 4, 5)); + } + + @Test + public void givenObservable_whenUsingToSortedList_thenObtainedASortedList() { + // given + Observable sourceObservable = Observable.range(10, 5); + TestSubscriber subscriber = TestSubscriber.create(); + + // when + Observable> listObservable = sourceObservable.toSortedList(); + listObservable.subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(Arrays.asList(10, 11, 12, 13, 14)); + } + + @Test + public void givenObservable_whenUsingToSortedListWithComparator_thenObtainedAnInverseSortedList() { + // given + Observable sourceObservable = Observable.range(10, 5); + TestSubscriber subscriber = TestSubscriber.create(); + + // when + Observable> listObservable = sourceObservable.toSortedList((int1, int2) -> int2 - int1); + listObservable.subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(Arrays.asList(14, 13, 12, 11, 10)); + } + + @Test + public void givenObservable_whenUsingToMap_thenObtainedAMap() { + // given + Observable bookObservable = Observable + .just( + new Book("The North Water", 2016), + new Book("Origin", 2017), + new Book("Sleeping Beauties", 2017)); + TestSubscriber subscriber = TestSubscriber.create(); + + // when + Observable> mapObservable = bookObservable + .toMap(Book::getTitle, Book::getYear, HashMap::new); + + mapObservable.subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(new HashMap() { + { + put("The North Water", 2016); + put("Origin", 2017); + put("Sleeping Beauties", 2017); + } + }); + } + + @Test + public void givenObservable_whenUsingToMultiMap_thenObtainedAMultiMap() { + // given + Observable bookObservable = Observable + .just( + new Book("The North Water", 2016), + new Book("Origin", 2017), + new Book("Sleeping Beauties", 2017)); + TestSubscriber subscriber = TestSubscriber.create(); + + // when + Observable multiMapObservable = bookObservable + .toMultimap(Book::getYear, Book::getTitle, () -> new HashMap<>(), (key) -> new ArrayList<>()); + + multiMapObservable.subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(new HashMap() { + { + put(2016, Arrays.asList("The North Water")); + put(2017, Arrays.asList("Origin", "Sleeping Beauties")); + } + }); + } + + class Book { + private String title; + private Integer year; + + public Book(String title, Integer year) { + this.title = title; + this.year = year; + } + + public String getTitle() { + return title; + } + + public Integer getYear() { + return year; + } + } +} diff --git a/rxjava/src/test/java/com/baeldung/rxjava/operators/RxMathematicalOperatorsTest.java b/rxjava/src/test/java/com/baeldung/rxjava/operators/RxMathematicalOperatorsTest.java new file mode 100644 index 0000000000..cd212a2e18 --- /dev/null +++ b/rxjava/src/test/java/com/baeldung/rxjava/operators/RxMathematicalOperatorsTest.java @@ -0,0 +1,139 @@ +package com.baeldung.rxjava.operators; + +import org.junit.Test; +import rx.Observable; +import rx.observables.MathObservable; +import rx.observers.TestSubscriber; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +public class RxMathematicalOperatorsTest { + + @Test + public void givenRangeNumericObservable_whenCalculatingAverage_ThenSuccessfull() { + // given + Observable sourceObservable = Observable.range(1, 20); + + TestSubscriber subscriber = TestSubscriber.create(); + + // when + MathObservable.averageInteger(sourceObservable) + .subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(10); + } + + @Test + public void givenRangeNumericObservable_whenCalculatingSum_ThenSuccessfull() { + // given + Observable sourceObservable = Observable.range(1, 20); + TestSubscriber subscriber = TestSubscriber.create(); + + // when + MathObservable.sumInteger(sourceObservable) + .subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(210); + + } + + @Test + public void givenRangeNumericObservable_whenCalculatingMax_ThenSuccessfullObtainingMaxValue() { + // given + Observable sourceObservable = Observable.range(1, 20); + TestSubscriber subscriber = TestSubscriber.create(); + + // when + MathObservable.max(sourceObservable) + .subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(20); + } + + @Test + public void givenRangeNumericObservable_whenCalculatingMin_ThenSuccessfullObtainingMinValue() { + // given + Observable sourceObservable = Observable.range(1, 20); + TestSubscriber subscriber = TestSubscriber.create(); + + // when + MathObservable.min(sourceObservable) + .subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(1); + } + + @Test + public void givenItemObservable_whenCalculatingMaxWithComparator_ThenSuccessfullObtainingMaxItem() { + // given + Item five = new Item(5); + List list = Arrays.asList(new Item(1), new Item(2), new Item(3), new Item(4), five); + Observable itemObservable = Observable.from(list); + + TestSubscriber subscriber = TestSubscriber.create(); + + // when + MathObservable.from(itemObservable) + .max(Comparator.comparing(Item::getId)) + .subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(five); + + } + + @Test + public void givenItemObservable_whenCalculatingMinWithComparator_ThenSuccessfullObtainingMinItem() { + // given + Item one = new Item(1); + List list = Arrays.asList(one, new Item(2), new Item(3), new Item(4), new Item(5)); + TestSubscriber subscriber = TestSubscriber.create(); + Observable itemObservable = Observable.from(list); + + // when + MathObservable.from(itemObservable) + .min(Comparator.comparing(Item::getId)) + .subscribe(subscriber); + + // then + subscriber.assertCompleted(); + subscriber.assertNoErrors(); + subscriber.assertValueCount(1); + subscriber.assertValue(one); + + } + + class Item { + private Integer id; + + public Item(Integer id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + } +} diff --git a/rxjava/src/test/resources/actual_clob b/rxjava/src/test/resources/actual_clob new file mode 100644 index 0000000000..d7bc560556 --- /dev/null +++ b/rxjava/src/test/resources/actual_clob @@ -0,0 +1,1546 @@ +64.242.88.10 - - [07/Mar/2004:16:05:49 -0800] "GET /ops/SP/play//edit/Main/Double_bounce_sender?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:16:06:51 -0800] "GET /ops/SP/play//rdiff/TWiki/NewUserTemplate?rev1=1.3&rev2=1.2 HTTP/1.1" 200 4523 +64.242.88.10 - - [07/Mar/2004:16:10:02 -0800] "GET /mailman/listinfo/hsdivision HTTP/1.1" 200 6291 +64.242.88.10 - - [07/Mar/2004:16:11:58 -0800] "GET /ops/SP/play//view/TWiki/WikiSyntax HTTP/1.1" 200 7352 +64.242.88.10 - - [07/Mar/2004:16:20:55 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +64.242.88.10 - - [07/Mar/2004:16:23:12 -0800] "GET /ops/SP/play//oops/TWiki/AppendixFileSystem?template=oopsmore¶m1=1.12¶m2=1.12 HTTP/1.1" 200 11382 +64.242.88.10 - - [07/Mar/2004:16:24:16 -0800] "GET /ops/SP/play//view/Main/PeterThoeny HTTP/1.1" 200 4924 +64.242.88.10 - - [07/Mar/2004:16:29:16 -0800] "GET /ops/SP/play//edit/Main/Header_checks?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:16:30:29 -0800] "GET /ops/SP/play//attach/Main/OfficeLocations HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:16:31:48 -0800] "GET /ops/SP/play//view/TWiki/WebTopicEditTemplate HTTP/1.1" 200 3732 +64.242.88.10 - - [07/Mar/2004:16:32:50 -0800] "GET /ops/SP/play//view/Main/WebChanges HTTP/1.1" 200 40520 +64.242.88.10 - - [07/Mar/2004:16:33:53 -0800] "GET /ops/SP/play//edit/Main/Smtpd_etrn_restrictions?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:16:35:19 -0800] "GET /mailman/listinfo/business HTTP/1.1" 200 6379 +64.242.88.10 - - [07/Mar/2004:16:36:22 -0800] "GET /ops/SP/play//rdiff/Main/WebIndex?rev1=1.2&rev2=1.1 HTTP/1.1" 200 46373 +64.242.88.10 - - [07/Mar/2004:16:37:27 -0800] "GET /ops/SP/play//view/TWiki/DontNotify HTTP/1.1" 200 4140 +64.242.88.10 - - [07/Mar/2004:16:39:24 -0800] "GET /ops/SP/play//view/Main/TokyoOffice HTTP/1.1" 200 3853 +64.242.88.10 - - [07/Mar/2004:16:43:54 -0800] "GET /ops/SP/play//view/Main/MikeMannix HTTP/1.1" 200 3686 +64.242.88.10 - - [07/Mar/2004:16:45:56 -0800] "GET /ops/SP/play//attach/Main/PostfixCommands HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:16:47:12 -0800] "GET /robots.txt HTTP/1.1" 200 68 +64.242.88.10 - - [07/Mar/2004:16:47:46 -0800] "GET /ops/SP/play//rdiff/Know/ReadmeFirst?rev1=1.5&rev2=1.4 HTTP/1.1" 200 5724 +64.242.88.10 - - [07/Mar/2004:16:49:04 -0800] "GET /ops/SP/play//view/Main/TWikiGroups?rev=1.2 HTTP/1.1" 200 5162 +64.242.88.10 - - [07/Mar/2004:16:50:54 -0800] "GET /ops/SP/play//rdiff/Main/ConfigurationVariables HTTP/1.1" 200 59679 +64.242.88.10 - - [07/Mar/2004:16:52:35 -0800] "GET /ops/SP/play//edit/Main/Flush_service_name?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:16:53:46 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiRegistration HTTP/1.1" 200 34395 +64.242.88.10 - - [07/Mar/2004:16:54:55 -0800] "GET /ops/SP/play//rdiff/Main/NicholasLee HTTP/1.1" 200 7235 +64.242.88.10 - - [07/Mar/2004:16:56:39 -0800] "GET /ops/SP/play//view/Sandbox/WebHome?rev=1.6 HTTP/1.1" 200 8545 +64.242.88.10 - - [07/Mar/2004:16:58:54 -0800] "GET /mailman/listinfo/administration HTTP/1.1" 200 6459 +lordgun.org - - [07/Mar/2004:17:01:53 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +64.242.88.10 - - [07/Mar/2004:17:09:01 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Joris%20*Benschop[^A-Za-z] HTTP/1.1" 200 4284 +64.242.88.10 - - [07/Mar/2004:17:10:20 -0800] "GET /ops/SP/play//oops/TWiki/TextFormattingRules?template=oopsmore¶m1=1.37¶m2=1.37 HTTP/1.1" 200 11400 +64.242.88.10 - - [07/Mar/2004:17:13:50 -0800] "GET /ops/SP/play//edit/TWiki/DefaultPlugin?t=1078688936 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:17:16:00 -0800] "GET /ops/SP/play//search/Main/?scope=topic®ex=on&search=^g HTTP/1.1" 200 3675 +64.242.88.10 - - [07/Mar/2004:17:17:27 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^d HTTP/1.1" 200 5773 +lj1036.passgo.com - - [07/Mar/2004:17:18:36 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1090.passgo.com - - [07/Mar/2004:17:18:41 -0800] "GET /ops/SP/play//view/Main/LondonOffice HTTP/1.0" 200 3860 +64.242.88.10 - - [07/Mar/2004:17:21:44 -0800] "GET /ops/SP/play//attach/TWiki/TablePlugin HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:17:22:49 -0800] "GET /ops/SP/play//view/TWiki/ManagingWebs?rev=1.22 HTTP/1.1" 200 9310 +64.242.88.10 - - [07/Mar/2004:17:23:54 -0800] "GET /ops/SP/play//statistics/Main HTTP/1.1" 200 808 +64.242.88.10 - - [07/Mar/2004:17:26:30 -0800] "GET /ops/SP/play//view/TWiki/WikiCulture HTTP/1.1" 200 5935 +64.242.88.10 - - [07/Mar/2004:17:27:37 -0800] "GET /ops/SP/play//edit/Main/WebSearch?t=1078669682 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:17:28:45 -0800] "GET /ops/SP/play//oops/TWiki/ResetPassword?template=oopsmore¶m1=1.4¶m2=1.4 HTTP/1.1" 200 11281 +64.242.88.10 - - [07/Mar/2004:17:29:59 -0800] "GET /ops/SP/play//view/TWiki/ManagingWebs?skin=print HTTP/1.1" 200 8806 +64.242.88.10 - - [07/Mar/2004:17:31:39 -0800] "GET /ops/SP/play//edit/Main/UvscanAndPostFix?topicparent=Main.WebHome HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:17:35:35 -0800] "GET /ops/SP/play//view/TWiki/KlausWriessnegger HTTP/1.1" 200 3848 +64.242.88.10 - - [07/Mar/2004:17:39:39 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.1" 200 4081 +64.242.88.10 - - [07/Mar/2004:17:42:15 -0800] "GET /ops/SP/play//oops/TWiki/RichardDonkin?template=oopsmore¶m1=1.2¶m2=1.2 HTTP/1.1" 200 11281 +64.242.88.10 - - [07/Mar/2004:17:46:17 -0800] "GET /ops/SP/play//rdiff/TWiki/AlWilliams?rev1=1.3&rev2=1.2 HTTP/1.1" 200 4485 +64.242.88.10 - - [07/Mar/2004:17:47:43 -0800] "GET /ops/SP/play//rdiff/TWiki/AlWilliams?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5234 +64.242.88.10 - - [07/Mar/2004:17:50:44 -0800] "GET /ops/SP/play//view/TWiki/SvenDowideit HTTP/1.1" 200 3616 +64.242.88.10 - - [07/Mar/2004:17:53:45 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Office%20*Locations[^A-Za-z] HTTP/1.1" 200 7771 +64.242.88.10 - - [07/Mar/2004:17:56:54 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.31 HTTP/1.1" 200 23338 +64.242.88.10 - - [07/Mar/2004:17:58:00 -0800] "GET /ops/SP/play//edit/Main/KevinWGagel?t=1078670331 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:18:00:09 -0800] "GET /ops/SP/play//edit/Main/Virtual_mailbox_lock?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:18:02:10 -0800] "GET /ops/SP/play//view/Main/WebPreferences HTTP/1.1" 200 8820 +64.242.88.10 - - [07/Mar/2004:18:04:05 -0800] "GET /ops/SP/play//view/TWiki/WikiWord?rev=1.3 HTTP/1.1" 200 6816 +lj1125.passgo.com - - [07/Mar/2004:18:06:14 -0800] "GET /ops/SP/play//oops/Sandbox/WebChanges HTTP/1.0" 200 209 +64.242.88.10 - - [07/Mar/2004:18:09:00 -0800] "GET /ops/SP/play//rdiff/Main/TWikiGuest HTTP/1.1" 200 11314 +64.242.88.10 - - [07/Mar/2004:18:10:09 -0800] "GET /ops/SP/play//edit/TWiki/TWikiVariables?t=1078684115 HTTP/1.1" 401 12846 +d207-6-9-183.bchsia.telus.net - - [07/Mar/2004:18:10:18 -0800] "GET /pipermail/cncce/2004-January/000001.jsp HTTP/1.1" 200 3095 +d207-6-9-183.bchsia.telus.net - - [07/Mar/2004:18:10:20 -0800] "GET /pipermail/cncce/2004-January/000002.jsp HTTP/1.1" 200 3810 +64.242.88.10 - - [07/Mar/2004:18:17:26 -0800] "GET /ops/SP/play//rdiff/TWiki/WikiWord?rev1=1.4&rev2=1.3 HTTP/1.1" 200 6948 +64.242.88.10 - - [07/Mar/2004:18:19:01 -0800] "GET /ops/SP/play//edit/Main/TWikiPreferences?topicparent=Main.WebHome HTTP/1.1" 401 12846 +d207-6-9-183.bchsia.telus.net - - [07/Mar/2004:18:19:16 -0800] "GET /pipermail/cncce/2004-January.txt HTTP/1.1" 200 3376 +64.242.88.10 - - [07/Mar/2004:18:22:52 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Web%20*Statistics[^A-Za-z] HTTP/1.1" 200 3584 +64.242.88.10 - - [07/Mar/2004:18:26:32 -0800] "GET /ops/SP/play//rdiff/TWiki/PeterFokkinga?rev1=1.4&rev2=1.3 HTTP/1.1" 200 4548 +64.242.88.10 - - [07/Mar/2004:18:32:39 -0800] "GET /mailman/listinfo/dentalstudies HTTP/1.1" 200 6345 +64.242.88.10 - - [07/Mar/2004:18:34:42 -0800] "GET /ops/SP/play//view/Main/TWikiGuest HTTP/1.1" 200 4449 +64.242.88.10 - - [07/Mar/2004:18:42:29 -0800] "GET /ops/SP/play//attach/Main/TWikiGroups HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:18:46:00 -0800] "GET /ops/SP/play//rdiff/TWiki/TextFormattingRules?rev1=1.36&rev2=1.35 HTTP/1.1" 200 25416 +64.242.88.10 - - [07/Mar/2004:18:47:06 -0800] "GET /ops/SP/play//rdiff/Main/TWikiGroups?rev1=1.3&rev2=1.2 HTTP/1.1" 200 4308 +64.242.88.10 - - [07/Mar/2004:18:48:15 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=.* HTTP/1.1" 200 3544 +64.242.88.10 - - [07/Mar/2004:18:52:30 -0800] "GET /ops/SP/play//edit/Main/Trigger_timeout?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:18:53:55 -0800] "GET /ops/SP/play//oops/TWiki/TWikiSite?template=oopsmore¶m1=1.21¶m2=1.21 HTTP/1.1" 200 11284 +64.242.88.10 - - [07/Mar/2004:18:57:07 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.35 HTTP/1.1" 200 27248 +64.242.88.10 - - [07/Mar/2004:18:58:52 -0800] "GET /ops/SP/play//edit/Main/Mydestination?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:18:59:52 -0800] "GET /mailman/listinfo/fcd HTTP/1.1" 200 5967 +64.242.88.10 - - [07/Mar/2004:19:01:48 -0800] "GET /ops/SP/play//rdiff/Main/WebHome?rev1=1.28&rev2=1.27 HTTP/1.1" 200 3596 +64.242.88.10 - - [07/Mar/2004:19:03:58 -0800] "GET /ops/SP/play//edit/Main/Message_size_limit?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:19:08:55 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiHistory HTTP/1.1" 200 138789 +64.242.88.10 - - [07/Mar/2004:19:10:13 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^y HTTP/1.1" 200 3628 +64.242.88.10 - - [07/Mar/2004:19:15:38 -0800] "GET /ops/SP/play//edit/Main/Smtpd_history_flush_threshold?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:19:16:44 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=1.59 HTTP/1.1" 200 52854 +64.242.88.10 - - [07/Mar/2004:19:18:05 -0800] "GET /ops/SP/play//edit/Main/Sender_canonical_maps?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:19:19:19 -0800] "GET /mailman/listinfo/mlc HTTP/1.1" 200 6142 +64.242.88.10 - - [07/Mar/2004:19:21:01 -0800] "GET /ops/SP/play//rdiff/Main/WebChanges HTTP/1.1" 200 114241 +64.242.88.10 - - [07/Mar/2004:19:22:11 -0800] "GET /ops/SP/play//edit/Sandbox/TestTopic5?topicparent=Sandbox.WebHome HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:19:24:57 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.22 HTTP/1.1" 200 21162 +64.242.88.10 - - [07/Mar/2004:19:26:22 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^j HTTP/1.1" 200 4524 +64.242.88.10 - - [07/Mar/2004:19:29:46 -0800] "GET /ops/SP/play//oops/TWiki/TWikiVariables?template=oopsmore¶m1=1.62¶m2=1.62 HTTP/1.1" 200 11444 +64.242.88.10 - - [07/Mar/2004:19:31:25 -0800] "GET /ops/SP/play//edit/Main/Lmtp_connect_timeout?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:19:32:45 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^q HTTP/1.1" 200 2937 +64.242.88.10 - - [07/Mar/2004:19:36:14 -0800] "GET /ops/SP/play//view/TWiki/ManagingWebs?rev=1.21 HTTP/1.1" 200 9310 +64.242.88.10 - - [07/Mar/2004:19:39:40 -0800] "GET /ops/SP/play//edit/Main/Qmqpd_authorized_clients?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:19:41:33 -0800] "GET /ops/SP/play//edit/Main/Header_address_token_limit?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:19:42:45 -0800] "GET /ops/SP/play//edit/Main/Syslog_name?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +80-219-148-207.dclient.hispeed.ch - - [07/Mar/2004:19:47:36 -0800] "OPTIONS * HTTP/1.0" 200 - +64.242.88.10 - - [07/Mar/2004:19:49:28 -0800] "GET /ops/SP/play//oops/TWiki/TWikiHistory?template=oopsmore¶m1=1.61¶m2=1.61 HTTP/1.1" 200 11345 +64.242.88.10 - - [07/Mar/2004:19:52:28 -0800] "GET /ops/SP/play//view/TWiki/HaroldGottschalk HTTP/1.1" 200 3838 +64.242.88.10 - - [07/Mar/2004:19:54:33 -0800] "GET /ops/SP/play//view/TWiki/DefaultPlugin?rev=1.4 HTTP/1.1" 200 7298 +64.242.88.10 - - [07/Mar/2004:19:55:40 -0800] "GET /ops/SP/play//oops/TWiki/WelcomeGuest?template=oopsmore¶m1=1.20¶m2=1.20 HTTP/1.1" 200 11266 +64.242.88.10 - - [07/Mar/2004:19:56:41 -0800] "GET /ops/SP/play//rdiff/Main/WebIndex HTTP/1.1" 200 46373 +64.242.88.10 - - [07/Mar/2004:19:58:24 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiRegistration?rev1=1.10&rev2=1.9 HTTP/1.1" 200 3826 +64.242.88.10 - - [07/Mar/2004:20:00:06 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.21 HTTP/1.1" 200 20972 +64.242.88.10 - - [07/Mar/2004:20:02:13 -0800] "GET /ops/SP/play//attach/TWiki/DefaultPlugin HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:03:29 -0800] "GET /ops/SP/play//search/Main/?scope=topic®ex=on&search=^p HTTP/1.1" 200 7245 +206-15-133-181.dialup.ziplink.net - - [07/Mar/2004:20:04:03 -0800] "HEAD /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 0 +64.242.88.10 - - [07/Mar/2004:20:04:35 -0800] "GET /ops/SP/play//edit/Main/Smtp_pix_workaround_delay_time?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:07:12 -0800] "GET /ops/SP/play//edit/Main/Berkeley_db_create_buffer_size?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +mmscrm07-2.uah.goweb.net - - [07/Mar/2004:20:10:50 -0800] "GET /robots.txt HTTP/1.0" 200 68 +64.242.88.10 - - [07/Mar/2004:20:11:33 -0800] "GET /ops/SP/play//attach/TWiki/TWikiSite HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:12:55 -0800] "GET /ops/SP/play//edit/TWiki/TWikiSite?t=1078681794 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:23:35 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Web%20*Statistics[^A-Za-z] HTTP/1.1" 200 10118 +64.242.88.10 - - [07/Mar/2004:20:25:31 -0800] "GET /ops/SP/play//edit/Main/Defer_transports?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:31:40 -0800] "GET /ops/SP/play//rdiff/TWiki/SearchDoesNotWork HTTP/1.1" 200 6738 +64.242.88.10 - - [07/Mar/2004:20:35:28 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=TWiki%20*Admin%20*Group[^A-Za-z] HTTP/1.1" 200 7311 +64.242.88.10 - - [07/Mar/2004:20:38:14 -0800] "GET /ops/SP/play//rdiff/TWiki/ChangePassword HTTP/1.1" 200 16670 +64.242.88.10 - - [07/Mar/2004:20:40:41 -0800] "GET /ops/SP/play//rdiff/TWiki/SvenDowideit HTTP/1.1" 200 5277 +64.242.88.10 - - [07/Mar/2004:20:42:09 -0800] "GET /ops/SP/play//rdiff/TWiki/KevinKinnell?rev1=1.5&rev2=1.4 HTTP/1.1" 200 4982 +64.242.88.10 - - [07/Mar/2004:20:44:48 -0800] "GET /ops/SP/play//edit/Main/Undisclosed_recipients_header?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:55:43 -0800] "GET /mailman/listinfo/hs_support HTTP/1.1" 200 6294 +64.242.88.10 - - [07/Mar/2004:20:56:56 -0800] "GET /ops/SP/play//view/TWiki/WebTopicList HTTP/1.1" 200 14070 +64.242.88.10 - - [07/Mar/2004:20:58:27 -0800] "GET /ops/SP/play//attach/TWiki/WebPreferences HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:21:03:48 -0800] "GET /ops/SP/play//view/TWiki/TWikiFAQ HTTP/1.1" 200 12050 +64.242.88.10 - - [07/Mar/2004:21:06:05 -0800] "GET /ops/SP/play//oops/TWiki/DefaultPlugin?template=oopsmore¶m1=1.5¶m2=1.5 HTTP/1.1" 200 11281 +64.242.88.10 - - [07/Mar/2004:21:07:24 -0800] "GET /ops/SP/play//rdiff/TWiki/AppendixFileSystem?rev1=1.11&rev2=1.10 HTTP/1.1" 200 40578 +64.242.88.10 - - [07/Mar/2004:21:14:32 -0800] "GET /ops/SP/play//rdiff/TWiki/FileAttribute HTTP/1.1" 200 5846 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:17 -0800] "GET /twiki/view/Main/WebHome HTTP/1.1" 404 300 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:18 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:21 -0800] "GET /twiki/ HTTP/1.1" 200 782 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:23 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:23 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:33 -0800] "GET /ops/SP/play//view/Main/TWikiUsers HTTP/1.1" 200 6697 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:40 -0800] "GET /ops/SP/play//view/Main/KevinWGagel HTTP/1.1" 200 4901 +64.242.88.10 - - [07/Mar/2004:21:20:14 -0800] "GET /ops/SP/play//edit/TWiki/RichardDonkin?t=1078691832 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:21:21:40 -0800] "GET /ops/SP/play//oops/Main/DCC?template=oopsmore¶m1=1.1¶m2=1.1 HTTP/1.1" 200 6399 +64.242.88.10 - - [07/Mar/2004:21:23:38 -0800] "GET /ops/SP/play//view/TWiki/TWikiUpgradeTo01May2000 HTTP/1.1" 200 7463 +64.242.88.10 - - [07/Mar/2004:21:31:12 -0800] "GET /ops/SP/play//edit/Main/Mail_release_date?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:21:33:51 -0800] "GET /ops/SP/play//view/TWiki/TWikiPlugins?rev=1.19 HTTP/1.1" 200 26541 +bh02i525f01.au.ibm.com - - [07/Mar/2004:21:34:00 -0800] "GET /AmavisNew.jsp HTTP/1.0" 200 2300 +64.242.88.10 - - [07/Mar/2004:21:39:55 -0800] "GET /ops/SP/play//attach/Main/ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:21:41:04 -0800] "GET /mailman/listinfo/techcomm HTTP/1.1" 200 6155 +64.242.88.10 - - [07/Mar/2004:21:42:47 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=1.8 HTTP/1.1" 200 15618 +64.242.88.10 - - [07/Mar/2004:21:44:10 -0800] "GET /ops/SP/play//edit/Sandbox/TestTopic7?topicparent=Sandbox.WebHome HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:21:50:22 -0800] "GET /ops/SP/play//rdiff/TWiki/WebSearch HTTP/1.1" 200 55862 +64.242.88.10 - - [07/Mar/2004:21:52:05 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiTopics HTTP/1.1" 200 101445 +64.242.88.10 - - [07/Mar/2004:22:03:19 -0800] "GET /ops/SP/play//rdiff/Main/VishaalGolam HTTP/1.1" 200 5055 +64.242.88.10 - - [07/Mar/2004:22:04:44 -0800] "GET /ops/SP/play//view/Main/TWikiUsers?rev=1.21 HTTP/1.1" 200 6522 +64.242.88.10 - - [07/Mar/2004:22:06:16 -0800] "GET /ops/SP/play//edit/Main/Delay_notice_recipient?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:07:33 -0800] "GET /ops/SP/play//view/TWiki/WikiNotation HTTP/1.1" 200 3617 +64.242.88.10 - - [07/Mar/2004:22:08:43 -0800] "GET /ops/SP/play//edit/Main/Forward_expansion_filter?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:09:44 -0800] "GET /ops/SP/play//edit/Main/TestArea?topicparent=Main.WebHome HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:10:55 -0800] "GET /ops/SP/play//view/Main/TokyoOffice?rev=1.2 HTTP/1.1" 200 4366 +64.242.88.10 - - [07/Mar/2004:22:12:28 -0800] "GET /ops/SP/play//attach/TWiki/WebSearch HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:15:57 -0800] "GET /mailman/listinfo/hs_rcafaculty HTTP/1.1" 200 6345 +64.242.88.10 - - [07/Mar/2004:22:17:40 -0800] "GET /ops/SP/play//view/TWiki/TWikiSkins?skin=print HTTP/1.1" 200 9563 +64.242.88.10 - - [07/Mar/2004:22:27:18 -0800] "GET /ops/SP/play//edit/Main/OfficeLocations?t=1078691049 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:29:10 -0800] "GET /ops/SP/play//view/Main/ThanadonSomdee HTTP/1.1" 200 4611 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:29:12 -0800] "GET /mailman/options/cnc_notice/arobin%40shaw.c HTTP/1.1" 200 3382 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:29:13 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:29:13 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:29:13 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:29:41 -0800] "POST /mailman/options/cnc_notice HTTP/1.1" 200 3533 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:30:08 -0800] "POST /mailman/options/cnc_notice HTTP/1.1" 200 13973 +64.242.88.10 - - [07/Mar/2004:22:31:25 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.16 HTTP/1.1" 200 17361 +64.242.88.10 - - [07/Mar/2004:22:35:53 -0800] "GET /ops/SP/play//edit/Main/Default_delivery_slot_discount?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:22:36:58 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiHistory?rev1=1.10&rev2=1.9 HTTP/1.1" 200 5336 +64.242.88.10 - - [07/Mar/2004:22:39:00 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Al%20*Williams[^A-Za-z] HTTP/1.1" 200 4364 +64.242.88.10 - - [07/Mar/2004:22:45:46 -0800] "GET /ops/SP/play//edit/Main/Smtpd_banner?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:47:19 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=r1.9 HTTP/1.1" 200 9133 +64.242.88.10 - - [07/Mar/2004:22:48:55 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiSkins?rev1=1.10&rev2=1.9 HTTP/1.1" 200 5989 +64.242.88.10 - - [07/Mar/2004:22:51:55 -0800] "GET /ops/SP/play//attach/TWiki/AndreaSterbini HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:22:53:36 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiPlugins?rev1=1.20&rev2=1.19 HTTP/1.1" 200 5140 +64.242.88.10 - - [07/Mar/2004:22:54:43 -0800] "GET /ops/SP/play//view/Know/ReadmeFirst?rev=1.4 HTTP/1.1" 200 6736 +64.242.88.10 - - [07/Mar/2004:22:58:24 -0800] "GET /ops/SP/play//view/Main/TokyoOffice?rev=r1.3 HTTP/1.1" 200 3853 +64.242.88.10 - - [07/Mar/2004:23:09:07 -0800] "GET /ops/SP/play//view/TWiki/AlWilliams?rev=1.1 HTTP/1.1" 200 3697 +calcite.rhyolite.com - - [07/Mar/2004:23:10:27 -0800] "GET /clients.jsp HTTP/1.1" 200 18753 +64.242.88.10 - - [07/Mar/2004:23:10:44 -0800] "GET /ops/SP/play//view/TWiki/JohnTalintyre HTTP/1.1" 200 3766 +64.242.88.10 - - [07/Mar/2004:23:13:51 -0800] "GET /ops/SP/play//view/TWiki/TWikiDocGraphics HTTP/1.1" 200 14492 +64.242.88.10 - - [07/Mar/2004:23:15:51 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.24 HTTP/1.1" 200 20981 +64.242.88.10 - - [07/Mar/2004:23:16:57 -0800] "GET /ops/SP/play//rdiff/Main/SanJoseOffice HTTP/1.1" 200 9524 +64.242.88.10 - - [07/Mar/2004:23:19:01 -0800] "GET /ops/SP/play//rdiff/Main/WebNotify HTTP/1.1" 200 16853 +64.242.88.10 - - [07/Mar/2004:23:20:26 -0800] "GET /ops/SP/play//view/TWiki/TWikiSiteTools HTTP/1.1" 200 14435 +64.242.88.10 - - [07/Mar/2004:23:23:00 -0800] "GET /ops/SP/play//rdiff/TWiki/RichardDonkin?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5891 +64.242.88.10 - - [07/Mar/2004:23:27:26 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Web%20*Preferences[^A-Za-z] HTTP/1.1" 200 20030 +64.242.88.10 - - [07/Mar/2004:23:30:23 -0800] "GET /ops/SP/play//rdiff/TWiki/WebHome HTTP/1.1" 200 108162 +64.242.88.10 - - [07/Mar/2004:23:34:31 -0800] "GET /ops/SP/play//edit/Main/Lmtp_quit_timeout?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:23:36:48 -0800] "GET /ops/SP/play//view/TWiki/WebSiteTools HTTP/1.1" 200 5208 +lj1036.passgo.com - - [07/Mar/2004:23:36:59 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1088.passgo.com - - [07/Mar/2004:23:36:59 -0800] "GET /ops/SP/play//oops/TWiki/JohnAltstadt HTTP/1.0" 200 209 +64.242.88.10 - - [07/Mar/2004:23:37:48 -0800] "GET /ops/SP/play//oops/Main/FileAttachment?template=oopsmore¶m1=1.3¶m2=1.3 HTTP/1.1" 200 6612 +64.242.88.10 - - [07/Mar/2004:23:42:44 -0800] "GET /ops/SP/play//edit/Main/Cleanup_service_name?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:23:47:58 -0800] "GET /ops/SP/play//view/TWiki/WikiReferences?skin=print HTTP/1.1" 200 5596 +64.242.88.10 - - [07/Mar/2004:23:50:03 -0800] "GET /ops/SP/play//view/Main/TokyoOffice?rev=1.3 HTTP/1.1" 200 3853 +64.242.88.10 - - [07/Mar/2004:23:51:38 -0800] "GET /ops/SP/play//view/Main/PostSuper?rev=r1.1 HTTP/1.1" 200 3629 +64.242.88.10 - - [07/Mar/2004:23:56:30 -0800] "GET /ops/SP/play//rdiff/Main/PostQueue HTTP/1.1" 200 4662 +64.242.88.10 - - [07/Mar/2004:23:58:53 -0800] "GET /ops/SP/play//edit/TWiki/TablePlugin?t=1078681446 HTTP/1.1" 401 12851 +dsl-80-43-113-44.access.uk.tiscali.com - - [08/Mar/2004:00:05:30 -0800] "GET / HTTP/1.1" 200 3169 +dsl-80-43-113-44.access.uk.tiscali.com - - [08/Mar/2004:00:05:35 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +dsl-80-43-113-44.access.uk.tiscali.com - - [08/Mar/2004:00:06:32 -0800] "GET /DCC.jsp HTTP/1.1" 200 2878 +64.242.88.10 - - [08/Mar/2004:00:08:58 -0800] "GET /ops/SP/play//oops/Sandbox/WebHome?template=oopsmore¶m1=1.7¶m2=1.7 HTTP/1.1" 200 4226 +64.242.88.10 - - [08/Mar/2004:00:11:22 -0800] "GET /ops/SP/play//edit/Main/WelcomeGuest?topicparent=Main.WebHome HTTP/1.1" 401 12846 +lj1125.passgo.com - - [08/Mar/2004:00:17:00 -0800] "GET /ops/SP/play//oops/Main/TWiki HTTP/1.0" 200 209 +64.242.88.10 - - [08/Mar/2004:00:17:22 -0800] "GET /ops/SP/play//view/TWiki/RichardDonkin?skin=print HTTP/1.1" 200 1729 +64.242.88.10 - - [08/Mar/2004:00:19:51 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=r1.4 HTTP/1.1" 200 7049 +64.242.88.10 - - [08/Mar/2004:00:21:54 -0800] "GET /ops/SP/play//view/TWiki/TWikiRegistration?rev=r1.7 HTTP/1.1" 200 12737 +64.242.88.10 - - [08/Mar/2004:00:25:11 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.26 HTTP/1.1" 200 22710 +64.242.88.10 - - [08/Mar/2004:00:27:53 -0800] "GET /ops/SP/play//view/TWiki/GoBox HTTP/1.1" 200 3762 +64.242.88.10 - - [08/Mar/2004:00:29:13 -0800] "GET /ops/SP/play//view/Main/FileAttachment?rev=1.1 HTTP/1.1" 200 17757 +64.242.88.10 - - [08/Mar/2004:00:32:45 -0800] "GET /ops/SP/play//attach/TWiki/KevinKinnell HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:00:36:21 -0800] "GET /ops/SP/play//rdiff/TWiki/WikiWikiClones HTTP/1.1" 200 9259 +64.242.88.10 - - [08/Mar/2004:00:37:23 -0800] "GET /ops/SP/play//oops/Main/NicholasLee?template=oopsmore¶m1=1.2¶m2=1.2 HTTP/1.1" 200 6558 +64.242.88.10 - - [08/Mar/2004:00:40:10 -0800] "GET /ops/SP/play//edit/Main/TWikiForms?topicparent=Main.TWikiVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:00:43:43 -0800] "GET /ops/SP/play//rdiff/TWiki/DefaultPlugin HTTP/1.1" 200 20376 +64.242.88.10 - - [08/Mar/2004:00:50:59 -0800] "GET /mailman/admin/educationadmin HTTP/1.1" 200 2150 +64.242.88.10 - - [08/Mar/2004:00:52:12 -0800] "GET /mailman/private/hsdivision/ HTTP/1.1" 200 1549 +64.242.88.10 - - [08/Mar/2004:00:54:26 -0800] "GET /mailman/listinfo/artsscience HTTP/1.1" 200 6248 +64.242.88.10 - - [08/Mar/2004:00:55:38 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^i HTTP/1.1" 200 7226 +64.242.88.10 - - [08/Mar/2004:01:00:08 -0800] "GET /ops/SP/play//rdiff/TWiki/AdrianLynch HTTP/1.1" 200 4011 +64.242.88.10 - - [08/Mar/2004:01:01:15 -0800] "GET /ops/SP/play//view/Main/WelcomeGuest HTTP/1.1" 200 4723 +64.242.88.10 - - [08/Mar/2004:01:02:16 -0800] "GET /ops/SP/play//view/Main/MikeMannix?rev=1.3 HTTP/1.1" 200 4721 +64.242.88.10 - - [08/Mar/2004:01:04:05 -0800] "GET /ops/SP/play//edit/TWiki/WikiStyleWord?topicparent=TWiki.TextFormattingFAQ HTTP/1.1" 401 12846 +lj1089.passgo.com - - [08/Mar/2004:01:04:54 -0800] "GET /ops/SP/play//oops/TWiki/InterWikis HTTP/1.0" 200 209 +64.242.88.10 - - [08/Mar/2004:01:10:43 -0800] "GET /ops/SP/play//view/TWiki/FormattedSearch?rev=1.8 HTTP/1.1" 200 20434 +64.242.88.10 - - [08/Mar/2004:01:12:20 -0800] "GET /ops/SP/play//view/TWiki/TWikiEnhancementRequests?rev=1.3 HTTP/1.1" 200 4379 +64.242.88.10 - - [08/Mar/2004:01:16:37 -0800] "GET /ops/SP/play//view/Main/FileAttachment?rev=1.2 HTTP/1.1" 200 17919 +64.242.88.10 - - [08/Mar/2004:01:19:18 -0800] "GET /ops/SP/play//edit/TWiki/AppendixFileSystem?t=1078674582 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:01:24:13 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.33 HTTP/1.1" 200 26294 +64.242.88.10 - - [08/Mar/2004:01:25:15 -0800] "GET /ops/SP/play//search/Main/?scope=topic®ex=on&search=^t HTTP/1.1" 200 8306 +64.242.88.10 - - [08/Mar/2004:01:29:17 -0800] "GET /ops/SP/play//oops/TWiki/TWikiPlugins?template=oopsmore¶m1=1.21¶m2=1.21 HTTP/1.1" 200 11341 +64.242.88.10 - - [08/Mar/2004:01:30:39 -0800] "GET /mailman/private/sswk/ HTTP/1.1" 200 1531 +64.242.88.10 - - [08/Mar/2004:01:33:14 -0800] "GET /mailman/private/business/ HTTP/1.1" 200 1543 +64.242.88.10 - - [08/Mar/2004:01:35:13 -0800] "GET /ops/SP/play//edit/TWiki/InterWikis?t=1078696998 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:01:41:14 -0800] "GET /ops/SP/play//view/TWiki/WelcomeGuest?rev=r1.18 HTTP/1.1" 200 14001 +64.242.88.10 - - [08/Mar/2004:01:46:05 -0800] "GET /ops/SP/play//search/TWiki/?search=\\.*&scope=topic&order=modified&reverse=on®ex=on&nosearch=on&limit=200 HTTP/1.1" 200 101279 +64.242.88.10 - - [08/Mar/2004:01:47:06 -0800] "GET /ops/SP/play//edit/TWiki/TWikiPages?topicparent=TWiki.WelcomeGuest HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:01:48:06 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=r1.16 HTTP/1.1" 200 9342 +64.242.88.10 - - [08/Mar/2004:01:50:37 -0800] "GET /ops/SP/play//rdiff/TWiki/RyanFreebern?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5243 +64.242.88.10 - - [08/Mar/2004:01:59:13 -0800] "GET /ops/SP/play//edit/Main/Smtp_line_length_limit?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:02:00:30 -0800] "GET /ops/SP/play//view/Main/WebStatistics?skin=print HTTP/1.1" 200 6194 +64.242.88.10 - - [08/Mar/2004:02:01:34 -0800] "GET /mailman/listinfo/webber HTTP/1.1" 200 6051 +64.242.88.10 - - [08/Mar/2004:02:03:12 -0800] "GET /mailman/admin/mlc HTTP/1.1" 200 2060 +64.242.88.10 - - [08/Mar/2004:02:05:15 -0800] "GET /mailman/listinfo/jjec HTTP/1.1" 200 6297 +64.242.88.10 - - [08/Mar/2004:02:06:17 -0800] "GET /mailman/listinfo/deans HTTP/1.1" 200 6102 +64.242.88.10 - - [08/Mar/2004:02:07:21 -0800] "GET /mailman/listinfo/gisgrad HTTP/1.1" 200 6024 +64.242.88.10 - - [08/Mar/2004:02:09:08 -0800] "GET /ops/SP/play//view/Main/WebNotify HTTP/1.1" 200 4468 +64.242.88.10 - - [08/Mar/2004:02:12:24 -0800] "GET /ops/SP/play//edit/Main/Setgid_group?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:02:16:24 -0800] "GET /ops/SP/play//view/Main/WebChanges?skin=print HTTP/1.1" 200 38580 +lj1016.passgo.com - - [08/Mar/2004:02:17:10 -0800] "GET /ops/SP/play//oops/TWiki/FileAttachment HTTP/1.0" 200 209 +lj1036.passgo.com - - [08/Mar/2004:02:22:19 -0800] "GET /ops/SP/play//view/Main/TWi HTTP/1.0" 200 4866 +64.242.88.10 - - [08/Mar/2004:02:23:45 -0800] "GET /ops/SP/play//rdiff/TWiki/IncludeTopicsAndWebPages HTTP/1.1" 200 20972 +64.242.88.10 - - [08/Mar/2004:02:26:44 -0800] "GET /ops/SP/play//oops/Main/WebChanges?template=oopsmore¶m1=1.2¶m2=1.2 HTTP/1.1" 200 6540 +64.242.88.10 - - [08/Mar/2004:02:27:51 -0800] "GET /ops/SP/play//rdiff/TWiki/InstantEnhancements HTTP/1.1" 200 25123 +64.242.88.10 - - [08/Mar/2004:02:33:28 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiPreferences?rev1=1.47&rev2=1.46 HTTP/1.1" 200 4313 +64.242.88.10 - - [08/Mar/2004:02:34:40 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=r1.24 HTTP/1.1" 200 9769 +64.242.88.10 - - [08/Mar/2004:02:42:36 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +64.242.88.10 - - [08/Mar/2004:02:45:03 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&bookview=on&search=.* HTTP/1.1" 200 102399 +64.242.88.10 - - [08/Mar/2004:02:46:12 -0800] "GET /ops/SP/play//edit/Main/Local_recipient_maps?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:02:47:58 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +lj1025.passgo.com - - [08/Mar/2004:02:48:05 -0800] "GET /ops/SP/play//oops/Main/KevinWGage HTTP/1.0" 200 209 +prxint-sxb3.e-i.net - - [08/Mar/2004:02:50:53 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +prxint-sxb3.e-i.net - - [08/Mar/2004:02:50:54 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +64.242.88.10 - - [08/Mar/2004:02:52:39 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.1" 200 4173 +prxint-sxb2.e-i.net - - [08/Mar/2004:02:54:29 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.0" 200 4022 +64.242.88.10 - - [08/Mar/2004:02:54:54 -0800] "GET /ops/SP/play//edit/TWiki/NewTopic?topicparent=TWiki.WikiSyntax HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:02:59:03 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiSite HTTP/1.1" 200 71941 +64.242.88.10 - - [08/Mar/2004:03:01:12 -0800] "GET /ops/SP/play//rdiff/TWiki/SimultaneousEdits HTTP/1.1" 200 6180 +64.242.88.10 - - [08/Mar/2004:03:06:31 -0800] "GET /ops/SP/play//view/Main/NicholasLee?rev=1.2 HTTP/1.1" 200 3570 +64.242.88.10 - - [08/Mar/2004:03:07:59 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=1.9 HTTP/1.1" 200 15756 +64.242.88.10 - - [08/Mar/2004:03:09:20 -0800] "GET /mailman/listinfo/ncbnpfaculty HTTP/1.1" 200 6331 +64.242.88.10 - - [08/Mar/2004:03:11:28 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Inter%20*Wikis[^A-Za-z] HTTP/1.1" 200 5113 +64.242.88.10 - - [08/Mar/2004:03:16:22 -0800] "GET /ops/SP/play//oops/TWiki/TextFormattingFAQ?template=oopsmore¶m1=1.14¶m2=1.14 HTTP/1.1" 200 11364 +64.242.88.10 - - [08/Mar/2004:03:17:50 -0800] "GET /ops/SP/play//rdiff/Main/WebTopicList HTTP/1.1" 200 8004 +64.242.88.10 - - [08/Mar/2004:03:21:16 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +64.242.88.10 - - [08/Mar/2004:03:26:06 -0800] "GET /mailman/private/mlc/ HTTP/1.1" 200 1528 +64.242.88.10 - - [08/Mar/2004:03:28:02 -0800] "GET /ops/SP/play//view/TWiki/WikiName HTTP/1.1" 200 4811 +64.242.88.10 - - [08/Mar/2004:03:33:52 -0800] "GET /ops/SP/play//rdiff/Main/WebRss HTTP/1.1" 200 20726 +64.242.88.10 - - [08/Mar/2004:03:35:42 -0800] "GET /ops/SP/play//rdiff/TWiki/SvenDowideit?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5277 +rouble.cc.strath.ac.uk - - [08/Mar/2004:03:40:51 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +213.181.81.4 - - [08/Mar/2004:03:42:20 -0800] "GET /LateEmail.jsp HTTP/1.0" 200 7649 +64.242.88.10 - - [08/Mar/2004:03:46:27 -0800] "GET /ops/SP/play//edit/Main/Deliver_lock_attempts?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:03:48:18 -0800] "GET /ops/SP/play//edit/Main/Daemon_directory?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:03:49:24 -0800] "GET /ops/SP/play//rdiff/TWiki/KlausWriessnegger?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5421 +64.242.88.10 - - [08/Mar/2004:03:51:05 -0800] "GET /ops/SP/play//view/Main/TWikiGuest?rev=1.4 HTTP/1.1" 200 4719 +64.242.88.10 - - [08/Mar/2004:03:52:17 -0800] "GET /ops/SP/play//edit/Main/Relayhost?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +lj1036.passgo.com - - [08/Mar/2004:03:53:59 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1159.passgo.com - - [08/Mar/2004:03:54:03 -0800] "GET /ops/SP/play//oops/Main/TWi HTTP/1.0" 200 209 +64.242.88.10 - - [08/Mar/2004:03:55:09 -0800] "GET /ops/SP/play//edit/Main/BookView?topicparent=Main.TWikiVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:04:16:08 -0800] "GET /ops/SP/play//rdiff/TWiki/DeleteOrRenameATopic HTTP/1.1" 200 10254 +64.242.88.10 - - [08/Mar/2004:04:18:28 -0800] "GET /ops/SP/play//view/TWiki/DavidWarman HTTP/1.1" 200 3739 +64.242.88.10 - - [08/Mar/2004:04:20:48 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.28 HTTP/1.1" 200 22777 +64.242.88.10 - - [08/Mar/2004:04:21:53 -0800] "GET /ops/SP/play//rdiff/Main/PeterThoeny HTTP/1.1" 200 18927 +64.242.88.10 - - [08/Mar/2004:04:22:55 -0800] "GET /ops/SP/play//edit/TWiki/SvenDowideit?t=1078710644 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:04:24:47 -0800] "GET /ops/SP/play//edit/Main/RBLsHowTo?t=1078668449 HTTP/1.1" 401 12846 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:25:38 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.0" 200 5672 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:25:44 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:26:02 -0800] "GET /ops/SP/play//view/Main/SideBar HTTP/1.0" 200 3960 +64.242.88.10 - - [08/Mar/2004:04:26:02 -0800] "GET /ops/SP/play//rdiff/TWiki/DefaultPlugin?rev1=1.5&rev2=1.4 HTTP/1.1" 200 4911 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:26:11 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.0" 200 4515 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:28:34 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.0" 200 4213 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:28:38 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.0" 200 4004 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:28:41 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.0" 200 4154 +64.242.88.10 - - [08/Mar/2004:04:28:42 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiHistory?rev1=1.61&rev2=1.60 HTTP/1.1" 200 4898 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:28:52 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.0" 200 3617 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:29:00 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.0" 200 4646 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:29:11 -0800] "GET /ops/SP/play//view/Main/ConfigurationVariables HTTP/1.0" 200 58169 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:29:21 -0800] "GET /ops/SP/play//edit/Main/Propagate_unmatched_extensions?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:29:30 -0800] "GET /go/bin/test/TWikiDocGraphics/help.gif HTTP/1.0" 200 130 +64.242.88.10 - - [08/Mar/2004:04:33:25 -0800] "GET /mailman/admin/hs_support HTTP/1.1" 200 2120 +64.242.88.10 - - [08/Mar/2004:04:40:32 -0800] "GET /ops/SP/play//edit/Main/Always_bcc?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:04:43:52 -0800] "GET /ops/SP/play//view/TWiki/WelcomeGuest?rev=r1.5 HTTP/1.1" 200 9492 +64.242.88.10 - - [08/Mar/2004:04:52:13 -0800] "GET /ops/SP/play//rdiff/Main/TWikiGuest?rev1=1.5&rev2=1.4 HTTP/1.1" 200 6233 +64.242.88.10 - - [08/Mar/2004:04:55:40 -0800] "GET /ops/SP/play//edit/Main/Delay_warning_time?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:04:59:13 -0800] "GET /ops/SP/play//edit/TWiki/KlausWriessnegger?t=1078709735 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:05:00:42 -0800] "GET /ops/SP/play//rdiff/TWiki/StanleyKnutson HTTP/1.1" 200 5327 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:00:44 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:00:45 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:00:46 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:00:52 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:01:02 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:01:14 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +64.242.88.10 - - [08/Mar/2004:05:01:58 -0800] "GET /ops/SP/play//view/TWiki/WhatIsWikiWiki HTTP/1.1" 200 4234 +200.160.249.68.bmf.com.br - - [08/Mar/2004:05:02:06 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +200.160.249.68.bmf.com.br - - [08/Mar/2004:05:02:07 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +64.242.88.10 - - [08/Mar/2004:05:03:13 -0800] "GET /ops/SP/play//view/Main/WebIndex?rev=1.1 HTTP/1.1" 200 44960 +64.242.88.10 - - [08/Mar/2004:05:13:35 -0800] "GET /mailman/private/hs_support/ HTTP/1.1" 200 1549 +68-174-110-154.nyc.rr.com - - [08/Mar/2004:05:16:15 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +68-174-110-154.nyc.rr.com - - [08/Mar/2004:05:16:20 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +64.242.88.10 - - [08/Mar/2004:05:22:57 -0800] "GET /ops/SP/play//attach/Sandbox/WebHome HTTP/1.1" 401 12846 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:23:37 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +66-194-6-70.gen.twtelecom.net - - [08/Mar/2004:05:24:18 -0800] "GET / HTTP/1.1" 200 3169 +64.242.88.10 - - [08/Mar/2004:05:24:29 -0800] "GET /ops/SP/play//edit/TWiki/UnchangeableTopicBug?topicparent=TWiki.TWikiHistory HTTP/1.1" 401 12846 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:24:50 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:25:46 -0800] "GET /ops/SP/play//view/Main/Postfix HTTP/1.1" 200 3699 +64.242.88.10 - - [08/Mar/2004:05:26:02 -0800] "GET /ops/SP/play//view/Main/TWikiGuest?skin=print HTTP/1.1" 200 2372 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:26:06 -0800] "GET /ops/SP/play//edit/Main/UvscanAndPostFix?topicparent=Main.WebHome HTTP/1.1" 401 12851 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:26:08 -0800] "GET /go/bin/test/TWikiDocGraphics/help.gif HTTP/1.1" 200 130 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:26:16 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +64.242.88.10 - - [08/Mar/2004:05:30:07 -0800] "GET /ops/SP/play//view/TWiki/SvenDowideit?rev=1.1 HTTP/1.1" 200 3564 +64.242.88.10 - - [08/Mar/2004:05:31:47 -0800] "GET /ops/SP/play//edit/Main/Maps_rbl_reject_code?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +lj1027.passgo.com - - [08/Mar/2004:05:32:01 -0800] "GET /ops/SP/play//view/TWiki/2fa HTTP/1.0" 200 4615 +64.242.88.10 - - [08/Mar/2004:05:34:33 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Web%20*Changes[^A-Za-z] HTTP/1.1" 200 4829 +64.242.88.10 - - [08/Mar/2004:05:36:56 -0800] "GET /ops/SP/play//edit/Main/WebStatistics?t=1078690975 HTTP/1.1" 401 12851 +68-174-110-154.nyc.rr.com - - [08/Mar/2004:05:38:57 -0800] "GET /razor.jsp HTTP/1.1" 304 - +64.242.88.10 - - [08/Mar/2004:05:42:06 -0800] "GET /ops/SP/play//view/Main/RelayGateway?rev=1.3 HTTP/1.1" 200 4232 +64.242.88.10 - - [08/Mar/2004:05:47:38 -0800] "GET /robots.txt HTTP/1.1" 200 68 +64.242.88.10 - - [08/Mar/2004:05:48:48 -0800] "GET /ops/SP/play//rdiff/TWiki/KevinKinnell?rev1=1.4&rev2=1.3 HTTP/1.1" 200 4369 +64.242.88.10 - - [08/Mar/2004:05:51:45 -0800] "GET /ops/SP/play//view/TWiki/WelcomeGuest?rev=r1.11 HTTP/1.1" 200 13102 +64.242.88.10 - - [08/Mar/2004:05:56:08 -0800] "GET /ops/SP/play//view/TWiki/TWikiRegistration?rev=r1.4 HTTP/1.1" 200 12113 +64.242.88.10 - - [08/Mar/2004:05:57:15 -0800] "GET /ops/SP/play//edit/TWiki/TWikiCodevTWikiEnhancementRequests?topicparent=TWiki.TWikiHistory HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:05:58:39 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Peter%20*Fokkinga[^A-Za-z] HTTP/1.1" 200 4388 +64.242.88.10 - - [08/Mar/2004:06:01:51 -0800] "GET /ops/SP/play//attach/Main/WebPreferences HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:06:09:37 -0800] "GET /mailman/admin/hs_rcafaculty HTTP/1.1" 200 2144 +64.242.88.10 - - [08/Mar/2004:06:17:13 -0800] "GET /ops/SP/play//rdiff/TWiki/WebChanges HTTP/1.1" 200 114167 +64.242.88.10 - - [08/Mar/2004:06:20:36 -0800] "GET /ops/SP/play//view/Main/JorisBenschop?skin=print HTTP/1.1" 200 2717 +64.242.88.10 - - [08/Mar/2004:06:23:52 -0800] "GET /ops/SP/play//edit/TWiki/TestArea?topicparent=TWiki.WelcomeGuest HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:06:32:14 -0800] "GET /ops/SP/play//view/TWiki/WelcomeGuest?rev=r1.6 HTTP/1.1" 200 12620 +64.242.88.10 - - [08/Mar/2004:06:37:19 -0800] "GET /ops/SP/play//rdiff/TWiki/HaroldGottschalk?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5389 +64.242.88.10 - - [08/Mar/2004:06:41:22 -0800] "GET /pipermail/techcomm/ HTTP/1.1" 200 1176 +64.242.88.10 - - [08/Mar/2004:06:42:29 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.19 HTTP/1.1" 200 20488 +64.242.88.10 - - [08/Mar/2004:06:43:32 -0800] "GET /ops/SP/play//edit/Sandbox/TestTopic2?topicparent=Sandbox.WebHome HTTP/1.1" 401 12846 +128.227.88.79 - - [08/Mar/2004:06:47:41 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +128.227.88.79 - - [08/Mar/2004:06:47:41 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +64.242.88.10 - - [08/Mar/2004:06:49:27 -0800] "GET /ops/SP/play//attach/TWiki/InterWikis HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:06:54:30 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiSkins?rev1=1.11&rev2=1.10 HTTP/1.1" 200 5711 +64.242.88.10 - - [08/Mar/2004:06:57:09 -0800] "GET /ops/SP/play//rdiff/TWiki/WebNotify HTTP/1.1" 200 11780 +128.227.88.79 - - [08/Mar/2004:06:57:46 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +128.227.88.79 - - [08/Mar/2004:06:57:46 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +64.242.88.10 - - [08/Mar/2004:07:00:15 -0800] "GET /ops/SP/play//view/TWiki/DontNotify?rev=1.1 HTTP/1.1" 200 3965 +64.242.88.10 - - [08/Mar/2004:07:07:13 -0800] "GET /ops/SP/play//edit/Main/Masquerade_classes?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +128.227.88.79 - - [08/Mar/2004:07:09:12 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.1" 200 4081 +64.242.88.10 - - [08/Mar/2004:07:09:21 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=r1.10 HTTP/1.1" 200 8312 +64.242.88.10 - - [08/Mar/2004:07:10:26 -0800] "GET /ops/SP/play//view/TWiki/HaroldGottschalk?rev=1.2 HTTP/1.1" 200 3774 +64.242.88.10 - - [08/Mar/2004:07:11:37 -0800] "GET /ops/SP/play//edit/TWiki/TWikiCodevTWikiPlannedFeatures?topicparent=TWiki.TWikiHistory HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:07:12:39 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=r1.44 HTTP/1.1" 200 41434 +64.242.88.10 - - [08/Mar/2004:07:22:13 -0800] "GET /ops/SP/play//view/TWiki/PeterFokkinga?rev=1.2 HTTP/1.1" 200 3748 +64.242.88.10 - - [08/Mar/2004:07:23:38 -0800] "GET /ops/SP/play//edit/TWiki/TWikiPlugins?t=1078696313 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:07:24:43 -0800] "GET /mailman/listinfo/webct HTTP/1.1" 200 6377 +64.242.88.10 - - [08/Mar/2004:07:25:56 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +64.242.88.10 - - [08/Mar/2004:07:27:01 -0800] "GET /mailman/listinfo/faculty HTTP/1.1" 200 6054 +61.9.4.61 - - [08/Mar/2004:07:27:36 -0800] "GET /_vti_bin/owssvr.dll?UL=1&ACT=4&BUILD=2614&STRMVER=4&CAPREQ=0 HTTP/1.0" 404 284 +61.9.4.61 - - [08/Mar/2004:07:27:36 -0800] "GET /SpamAssassin.jsp HTTP/1.0" 200 7368 +61.9.4.61 - - [08/Mar/2004:07:27:37 -0800] "GET /MSOffice/cltreq.asp?UL=1&ACT=4&BUILD=2614&STRMVER=4&CAPREQ=0 HTTP/1.0" 404 284 +64.242.88.10 - - [08/Mar/2004:07:28:29 -0800] "GET /mailman/admin/sswk HTTP/1.1" 200 2072 +64.242.88.10 - - [08/Mar/2004:07:29:56 -0800] "GET /mailman/listinfo/purchasing HTTP/1.1" 200 6050 +64.242.88.10 - - [08/Mar/2004:07:35:50 -0800] "GET /ops/SP/play//edit/Main/Invalid_hostname_reject_code?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:07:39:31 -0800] "GET /ops/SP/play//rdiff/Main/WebPreferences?rev1=1.14&rev2=1.13 HTTP/1.1" 200 7207 +64.242.88.10 - - [08/Mar/2004:07:40:54 -0800] "GET /ops/SP/play//rename/TWiki/TWikiHistory HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:07:43:21 -0800] "GET /ops/SP/play//view/TWiki/SearchDoesNotWork?rev=r1.2 HTTP/1.1" 200 4072 +64.242.88.10 - - [08/Mar/2004:07:44:53 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=r1.50 HTTP/1.1" 200 42285 +64.242.88.10 - - [08/Mar/2004:07:49:56 -0800] "GET /ops/SP/play//edit/TWiki/RyanFreebern?t=1078701457 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:07:51:39 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=r1.2 HTTP/1.1" 200 6061 +64.242.88.10 - - [08/Mar/2004:07:53:19 -0800] "GET /ops/SP/play//rdiff/TWiki/WebTopicEditTemplate HTTP/1.1" 200 7895 +mcl02.tnr.on.ca - - [08/Mar/2004:07:53:37 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +mcl02.tnr.on.ca - - [08/Mar/2004:07:53:38 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +mcl02.tnr.on.ca - - [08/Mar/2004:07:53:38 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +mcl02.tnr.on.ca - - [08/Mar/2004:07:53:38 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +64.242.88.10 - - [08/Mar/2004:07:54:30 -0800] "GET /ops/SP/play//edit/Main/Unknown_local_recipient_reject_code?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:07:56:34 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Web%20*Index[^A-Za-z] HTTP/1.1" 200 4163 +64.242.88.10 - - [08/Mar/2004:08:04:46 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +p5083cd5d.dip0.t-ipconnect.de - - [08/Mar/2004:08:09:32 -0800] "GET /SpamAssassin.jsp HTTP/1.0" 200 7368 +64.242.88.10 - - [08/Mar/2004:08:12:50 -0800] "GET /ops/SP/play//view/TWiki/ChangePassword?rev=r1.6 HTTP/1.1" 200 5181 +64.242.88.10 - - [08/Mar/2004:08:14:15 -0800] "GET /ops/SP/play//edit/TWiki/HaroldGottschalk?t=1078717948 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:08:15:21 -0800] "GET /ops/SP/play//edit/Main/Expand_owner_alias?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:08:17:09 -0800] "GET /ops/SP/play//view/Main/WebIndex?rev=r1.2 HTTP/1.1" 200 45059 +64.242.88.10 - - [08/Mar/2004:08:18:52 -0800] "GET /rfc.jsp HTTP/1.1" 200 3103 +pool-68-160-195-60.ny325.east.verizon.net - - [08/Mar/2004:08:21:00 -0800] "GET / HTTP/1.1" 200 3169 +pool-68-160-195-60.ny325.east.verizon.net - - [08/Mar/2004:08:21:00 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +64.242.88.10 - - [08/Mar/2004:08:21:47 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=RBLs%20*How%20*To[^A-Za-z] HTTP/1.1" 200 3575 +64.242.88.10 - - [08/Mar/2004:08:25:37 -0800] "GET /ops/SP/play//rdiff/TWiki/WebTopicEditTemplate?rev1=1.5&rev2=1.4 HTTP/1.1" 200 4212 +212.92.37.62 - - [08/Mar/2004:08:26:41 -0800] "GET / HTTP/1.1" 200 3169 +212.92.37.62 - - [08/Mar/2004:08:27:04 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +212.92.37.62 - - [08/Mar/2004:08:27:08 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +64.242.88.10 - - [08/Mar/2004:08:27:14 -0800] "GET /ops/SP/play//rdiff/Main/SpamAssassin HTTP/1.1" 200 4445 +212.92.37.62 - - [08/Mar/2004:08:27:23 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +212.92.37.62 - - [08/Mar/2004:08:27:28 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +64.242.88.10 - - [08/Mar/2004:08:28:23 -0800] "GET /ops/SP/play//rdiff/Main/TokyoOffice?rev1=1.2&rev2=1.1 HTTP/1.1" 200 7316 +64.242.88.10 - - [08/Mar/2004:08:29:36 -0800] "GET /ops/SP/play//view/TWiki/TWikiCategoryTable HTTP/1.1" 200 3729 +219.95.17.51 - - [08/Mar/2004:08:29:57 -0800] "GET / HTTP/1.1" 200 3169 +212.92.37.62 - - [08/Mar/2004:08:30:25 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +212.92.37.62 - - [08/Mar/2004:08:31:37 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +10.0.0.176 - - [08/Mar/2004:08:32:24 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:08:32:27 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +10.0.0.176 - - [08/Mar/2004:08:32:27 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +212.92.37.62 - - [08/Mar/2004:08:32:34 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +212.92.37.62 - - [08/Mar/2004:08:33:27 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +212.92.37.62 - - [08/Mar/2004:08:33:30 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.1" 200 4173 +212.92.37.62 - - [08/Mar/2004:08:33:39 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.1" 200 3629 +64.242.88.10 - - [08/Mar/2004:08:33:51 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=r1.14 HTTP/1.1" 200 8820 +212.92.37.62 - - [08/Mar/2004:08:33:52 -0800] "GET /ops/SP/play//view/Main/SideBar HTTP/1.1" 200 3972 +212.92.37.62 - - [08/Mar/2004:08:33:57 -0800] "GET /ops/SP/play//view/Main/DCCGraphs HTTP/1.1" 200 5402 +212.92.37.62 - - [08/Mar/2004:08:34:09 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +64.242.88.10 - - [08/Mar/2004:08:34:53 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiHistory?rev1=1.8&rev2=1.7 HTTP/1.1" 200 4972 +64.242.88.10 - - [08/Mar/2004:08:36:05 -0800] "GET /ops/SP/play//view/TWiki/ChangePassword?rev=r1.3 HTTP/1.1" 200 5229 +92-moc-6.acn.waw.pl - - [08/Mar/2004:08:37:14 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +92-moc-6.acn.waw.pl - - [08/Mar/2004:08:37:14 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +92-moc-6.acn.waw.pl - - [08/Mar/2004:08:37:17 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +64.242.88.10 - - [08/Mar/2004:08:37:23 -0800] "GET /ops/SP/play//attach/TWiki/HaroldGottschalk HTTP/1.1" 401 12846 +66.213.206.2 - - [08/Mar/2004:08:37:53 -0800] "GET / HTTP/1.1" 200 3169 +64.242.88.10 - - [08/Mar/2004:08:40:15 -0800] "GET /LateEmail.jsp HTTP/1.1" 200 7649 +64.242.88.10 - - [08/Mar/2004:08:52:13 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.15 HTTP/1.1" 200 16746 +64.242.88.10 - - [08/Mar/2004:08:53:17 -0800] "GET /ops/SP/play//view/TWiki/TWikiTutorial HTTP/1.1" 200 14485 +64.242.88.10 - - [08/Mar/2004:08:55:12 -0800] "GET /mailman/private/dentalstudies/ HTTP/1.1" 200 1558 +spot.nnacorp.com - - [08/Mar/2004:09:02:14 -0800] "GET / HTTP/1.1" 200 3169 +spot.nnacorp.com - - [08/Mar/2004:09:02:21 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +spot.nnacorp.com - - [08/Mar/2004:09:02:21 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +10.0.0.176 - - [08/Mar/2004:09:02:29 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:09:02:31 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 7326 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 7927 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7182 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8866 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9307 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6805 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6596 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5499 +spot.nnacorp.com - - [08/Mar/2004:09:02:54 -0800] "GET /ops/SP/play//view/Main/TWikiUsers HTTP/1.1" 200 6697 +spot.nnacorp.com - - [08/Mar/2004:09:02:54 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +64.242.88.10 - - [08/Mar/2004:09:03:18 -0800] "GET /ststats/index.jsp HTTP/1.1" 200 2955 +64.242.88.10 - - [08/Mar/2004:09:05:54 -0800] "GET /ops/SP/play//edit/Sandbox/TestTopic6?topicparent=Sandbox.WebHome HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:09:09:55 -0800] "GET /ops/SP/play//view/TWiki/TablePlugin?skin=print HTTP/1.1" 200 1572 +64.242.88.10 - - [08/Mar/2004:09:12:54 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Spam%20*Assassin[^A-Za-z] HTTP/1.1" 200 8782 +lhr003a.dhl.com - - [08/Mar/2004:09:16:26 -0800] "GET / HTTP/1.0" 200 3169 +lhr003a.dhl.com - - [08/Mar/2004:09:17:16 -0800] "GET /ststats/index.jsp HTTP/1.0" 200 2955 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.0" 200 3040 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.0" 200 2341 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.0" 200 2271 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.0" 200 3302 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.0" 200 1663 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.0" 200 2521 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.0" 200 1918 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.0" 200 1580 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.0" 200 2202 +lhr003a.dhl.com - - [08/Mar/2004:09:17:18 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.0" 200 1822 +lhr003a.dhl.com - - [08/Mar/2004:09:17:18 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.0" 200 1526 +10.0.0.176 - - [08/Mar/2004:09:18:53 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:09:18:56 -0800] "GET /ststats/index.jsp HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3040 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2271 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2341 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3302 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1580 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1918 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1663 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2202 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2521 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1822 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1526 +64.242.88.10 - - [08/Mar/2004:09:23:03 -0800] "GET /ops/SP/play//view/TWiki/SearchDoesNotWork?rev=r1.1 HTTP/1.1" 200 3981 +64.242.88.10 - - [08/Mar/2004:09:25:42 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=TWiki%20*FAQ[^A-Za-z] HTTP/1.1" 200 12083 +lj1036.passgo.com - - [08/Mar/2004:09:29:35 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1027.passgo.com - - [08/Mar/2004:09:29:36 -0800] "GET /ops/SP/play//oops/Know/WinDoze95Crash HTTP/1.0" 200 209 +pool-68-160-195-60.ny325.east.verizon.net - - [08/Mar/2004:09:30:10 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +pool-68-160-195-60.ny325.east.verizon.net - - [08/Mar/2004:09:30:11 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +pool-68-160-195-60.ny325.east.verizon.net - - [08/Mar/2004:09:30:11 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +64.242.88.10 - - [08/Mar/2004:09:30:40 -0800] "GET /ops/SP/play//view/TWiki/WebSearch?rev=r1.10 HTTP/1.1" 200 9419 +64.242.88.10 - - [08/Mar/2004:09:32:32 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiDownload HTTP/1.1" 200 5933 +64.242.88.10 - - [08/Mar/2004:09:33:46 -0800] "GET /ops/SP/play//view/Main/SideBar?rev=1.1 HTTP/1.1" 200 3564 +lj1156.passgo.com - - [08/Mar/2004:09:33:53 -0800] "GET /ops/SP/play//oops/TWiki/TWikiAccessControl HTTP/1.0" 200 209 +64.242.88.10 - - [08/Mar/2004:09:34:58 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiFAQ HTTP/1.1" 200 43115 +64.242.88.10 - - [08/Mar/2004:09:36:35 -0800] "GET /ops/SP/play//edit/TWiki/WebNotification?topicparent=TWiki.TWikiUpgradeTo01May2000 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:09:38:11 -0800] "GET /ops/SP/play//view/Main/TWikiGuest?rev=r1.3 HTTP/1.1" 200 4604 +lj1156.passgo.com - - [08/Mar/2004:09:40:30 -0800] "GET /ops/SP/play//view/TWiki/d43 HTTP/1.0" 200 4619 +64.242.88.10 - - [08/Mar/2004:09:41:15 -0800] "GET /ops/SP/play//edit/Main/Export_environment?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:09:42:27 -0800] "GET /ops/SP/play//rdiff/Know/ReadmeFirst?rev1=1.6&rev2=1.5 HTTP/1.1" 200 4187 +64.242.88.10 - - [08/Mar/2004:09:45:15 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Change%20*Password[^A-Za-z] HTTP/1.1" 200 7226 +64.242.88.10 - - [08/Mar/2004:10:01:06 -0800] "GET /ops/SP/play//view/TWiki/TWikiTopics?rev=r1.4 HTTP/1.1" 200 5171 +64.242.88.10 - - [08/Mar/2004:10:05:40 -0800] "GET /ops/SP/play//view/TWiki/WebSearch?rev=r1.9 HTTP/1.1" 200 9469 +lj1164.passgo.com - - [08/Mar/2004:10:06:28 -0800] "GET /ops/SP/play//view/Main/DCCGraphs HTTP/1.0" 200 5383 +64.242.88.10 - - [08/Mar/2004:10:08:02 -0800] "GET /ops/SP/play//rename/TWiki/DefaultPlugin HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:10:09:52 -0800] "GET /ops/SP/play//view/Main/TWikiGuest?rev=r1.1 HTTP/1.1" 200 3763 +64.242.88.10 - - [08/Mar/2004:10:14:46 -0800] "GET /ops/SP/play//edit/TWiki/TWikiRegistration?t=1078670224 HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:10:16:52 -0800] "GET /ops/SP/play//view/Main/TWikiAdminGroup?rev=1.6 HTTP/1.1" 200 4462 +64.242.88.10 - - [08/Mar/2004:10:18:21 -0800] "GET /ops/SP/play//rdiff/TWiki/WikiSyntax HTTP/1.1" 200 59454 +64.242.88.10 - - [08/Mar/2004:10:21:21 -0800] "GET /ops/SP/play//oops/TWiki/WikiCulture?template=oopsmore¶m1=1.8¶m2=1.8 HTTP/1.1" 200 11245 +64.242.88.10 - - [08/Mar/2004:10:30:56 -0800] "GET /ops/SP/play//view/TWiki/WikiTopic HTTP/1.1" 200 4646 +64.242.88.10 - - [08/Mar/2004:10:32:18 -0800] "GET /ops/SP/play//rdiff/TWiki/WebPreferences HTTP/1.1" 200 36410 +64.242.88.10 - - [08/Mar/2004:10:34:55 -0800] "GET /ops/SP/play//view/TWiki/WebSearch?skin=print HTTP/1.1" 200 7196 +64.242.88.10 - - [08/Mar/2004:10:40:09 -0800] "GET /ops/SP/play//view/TWiki/TWikiTopics?rev=r1.7 HTTP/1.1" 200 8540 +64.242.88.10 - - [08/Mar/2004:10:45:25 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Thanadon%20*Somdee[^A-Za-z] HTTP/1.1" 200 4287 +64.242.88.10 - - [08/Mar/2004:10:46:34 -0800] "GET /ops/SP/play//view/TWiki/TWikiUpgradeTo01May2000?rev=1.3 HTTP/1.1" 200 7441 +10.0.0.176 - - [08/Mar/2004:10:48:02 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:10:48:05 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 7213 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 7970 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7254 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8821 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6866 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9312 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6596 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5499 +64.242.88.10 - - [08/Mar/2004:10:48:19 -0800] "GET /ops/SP/play//edit/Main/Max_use?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/index.jsp HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3080 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2224 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3299 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2481 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1667 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2346 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1872 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1585 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2202 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1833 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1521 +64.242.88.10 - - [08/Mar/2004:10:50:05 -0800] "GET /ops/SP/play//rdiff/TWiki/WebRss HTTP/1.1" 200 21483 +64.242.88.10 - - [08/Mar/2004:11:03:34 -0800] "GET /ops/SP/play//rdiff/TWiki/WikiCulture?rev1=1.8&rev2=1.7 HTTP/1.1" 200 5326 +128.227.88.79 - - [08/Mar/2004:11:06:20 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +128.227.88.79 - - [08/Mar/2004:11:06:20 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +128.227.88.79 - - [08/Mar/2004:11:06:28 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +64.242.88.10 - - [08/Mar/2004:11:09:24 -0800] "GET /ops/SP/play//edit/Main/Lmtp_mail_timeout?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +128.227.88.79 - - [08/Mar/2004:11:10:09 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +128.227.88.79 - - [08/Mar/2004:11:10:24 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +128.227.88.79 - - [08/Mar/2004:11:11:04 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +128.227.88.79 - - [08/Mar/2004:11:11:10 -0800] "GET /ops/SP/play//view/Main/TWikiGroups HTTP/1.1" 200 4816 +128.227.88.79 - - [08/Mar/2004:11:11:15 -0800] "GET /ops/SP/play//view/Main/TWikiAdminGroup HTTP/1.1" 200 4175 +128.227.88.79 - - [08/Mar/2004:11:11:26 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +64.242.88.10 - - [08/Mar/2004:11:11:51 -0800] "GET /ops/SP/play//edit/Main/TWikiGuest?t=1078713282 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:11:15:51 -0800] "GET /ops/SP/play//rdiff/TWiki/AdminSkillsAssumptions HTTP/1.1" 200 10368 +64.242.88.10 - - [08/Mar/2004:11:17:49 -0800] "GET /ops/SP/play//view/Sandbox/WebHome?rev=r1.3 HTTP/1.1" 200 8708 +64.242.88.10 - - [08/Mar/2004:11:19:43 -0800] "GET /ops/SP/play//edit/TWiki/WikiNotation?t=1078726052 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:11:24:12 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Wiki%20*Notation[^A-Za-z] HTTP/1.1" 200 6558 +64.242.88.10 - - [08/Mar/2004:11:25:16 -0800] "GET /ops/SP/play//oops/TWiki/WikiNotation?template=oopsmore¶m1=1.3¶m2=1.3 HTTP/1.1" 200 11263 +10.0.0.176 - - [08/Mar/2004:11:40:41 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 7226 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 8055 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8787 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7088 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6866 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6596 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9312 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5499 +64.242.88.10 - - [08/Mar/2004:11:41:14 -0800] "GET /mailman/admin/artsscience HTTP/1.1" 200 2125 +64.242.88.10 - - [08/Mar/2004:11:43:17 -0800] "GET /ops/SP/play//search/Main/?scope=topic®ex=on&search=^d HTTP/1.1" 200 5036 +64.242.88.10 - - [08/Mar/2004:11:45:08 -0800] "GET /ops/SP/play//edit/TWiki/TWikiCodevFeatureToDo?topicparent=TWiki.TWikiHistory HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:11:47:52 -0800] "GET /ops/SP/play//rename/TWiki/ResetPassword HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:11:49:23 -0800] "GET /ops/SP/play//edit/Main/Fast_flush_domains?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:11:51:20 -0800] "GET /ops/SP/play//edit/Main/SpamAssassin?t=1078709979 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:11:56:19 -0800] "GET /ops/SP/play//view/TWiki/TWikiTopics?rev=r1.10 HTTP/1.1" 200 14650 +64.242.88.10 - - [08/Mar/2004:11:57:28 -0800] "GET /ops/SP/play//view/TWiki/FileAttribute?rev=r1.2 HTTP/1.1" 200 3949 +64.242.88.10 - - [08/Mar/2004:12:00:26 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiEnhancementRequests HTTP/1.1" 200 10417 +64.242.88.10 - - [08/Mar/2004:12:06:03 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Kevin%20*Kinnell[^A-Za-z] HTTP/1.1" 200 4536 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 7192 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 8081 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 9065 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7206 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9312 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6866 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6596 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5499 +64.242.88.10 - - [08/Mar/2004:12:07:13 -0800] "GET /ops/SP/play//view/TWiki/FileAttribute?rev=1.2 HTTP/1.1" 200 3949 +64.242.88.10 - - [08/Mar/2004:12:08:32 -0800] "GET /ops/SP/play//view/TWiki/WikiNotation?skin=print HTTP/1.1" 200 1435 +64.242.88.10 - - [08/Mar/2004:12:10:39 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiPlannedFeatures HTTP/1.1" 200 10577 +64.242.88.10 - - [08/Mar/2004:12:12:50 -0800] "GET /mailman/admin/deans HTTP/1.1" 200 2080 +64.242.88.10 - - [08/Mar/2004:12:15:36 -0800] "GET /pipermail/webber/ HTTP/1.1" 200 1161 +64.242.88.10 - - [08/Mar/2004:12:20:18 -0800] "GET /ops/SP/play//view/Main/PostSuper?rev=1.1 HTTP/1.1" 200 3629 +64.242.88.10 - - [08/Mar/2004:12:25:47 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=1.13 HTTP/1.1" 200 8770 +64.242.88.10 - - [08/Mar/2004:12:28:09 -0800] "GET /ops/SP/play//edit/Main/Mailq_path?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:12:31:32 -0800] "GET /ops/SP/play//view/TWiki/WebHome?rev=r1.49 HTTP/1.1" 200 12993 +64.242.88.10 - - [08/Mar/2004:12:33:09 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=r1.49 HTTP/1.1" 200 42243 +64.242.88.10 - - [08/Mar/2004:12:39:34 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiDocGraphics?rev1=1.11&rev2=1.10 HTTP/1.1" 200 6551 +64.242.88.10 - - [08/Mar/2004:12:40:36 -0800] "GET /ops/SP/play//view/TWiki/WebHome?rev=r1.47 HTTP/1.1" 200 12819 +64.242.88.10 - - [08/Mar/2004:12:42:04 -0800] "GET /ops/SP/play//view/Sandbox/WebStatistics HTTP/1.1" 200 6063 +64.242.88.10 - - [08/Mar/2004:12:43:08 -0800] "GET /pipermail/gisgrad/ HTTP/1.1" 200 1118 +64.242.88.10 - - [08/Mar/2004:12:45:13 -0800] "GET /mailman/admin/webber HTTP/1.1" 200 2089 +64.242.88.10 - - [08/Mar/2004:12:47:42 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=1.14 HTTP/1.1" 200 8820 +64.242.88.10 - - [08/Mar/2004:12:55:18 -0800] "GET /ops/SP/play//view/TWiki/KevinKinnell?rev=1.4 HTTP/1.1" 200 3730 +64.242.88.10 - - [08/Mar/2004:12:58:39 -0800] "GET /ops/SP/play//search/Main/?search=\\.*&scope=topic&order=modified&reverse=on®ex=on&nosearch=on&limit=800 HTTP/1.1" 200 43915 +market-mail.panduit.com - - [08/Mar/2004:12:58:50 -0800] "GET / HTTP/1.0" 200 3169 +market-mail.panduit.com - - [08/Mar/2004:12:58:50 -0800] "GET /favicon.ico HTTP/1.0" 200 1078 +market-mail.panduit.com - - [08/Mar/2004:12:59:18 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +market-mail.panduit.com - - [08/Mar/2004:12:59:34 -0800] "GET /ststats/index.jsp HTTP/1.0" 200 2955 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.0" 200 3095 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.0" 200 2272 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.0" 200 3279 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.0" 200 2349 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.0" 200 1659 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.0" 200 2542 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.0" 200 1927 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.0" 200 1580 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.0" 200 2201 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.0" 200 1829 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.0" 200 1524 +market-mail.panduit.com - - [08/Mar/2004:12:59:55 -0800] "GET /DCC.jsp HTTP/1.0" 200 2878 +market-mail.panduit.com - - [08/Mar/2004:13:00:12 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +market-mail.panduit.com - - [08/Mar/2004:13:00:12 -0800] "GET /favicon.ico HTTP/1.0" 200 1078 +market-mail.panduit.com - - [08/Mar/2004:13:00:13 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +market-mail.panduit.com - - [08/Mar/2004:13:00:20 -0800] "GET /ops/SP/play//view/Main/DCC HTTP/1.0" 200 4377 +market-mail.panduit.com - - [08/Mar/2004:13:00:27 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.0" 200 5234 +64.242.88.10 - - [08/Mar/2004:13:00:40 -0800] "GET /ops/SP/play//oops/TWiki/HaroldGottschalk?template=oopsmore¶m1=1.3¶m2=1.3 HTTP/1.1" 200 11335 +market-mail.panduit.com - - [08/Mar/2004:13:01:27 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.0" 200 4004 +market-mail.panduit.com - - [08/Mar/2004:13:01:29 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.0" 200 4154 +market-mail.panduit.com - - [08/Mar/2004:13:01:35 -0800] "GET /ops/SP/play//edit/Main/PostConf?topicparent=Main.PostfixCommands HTTP/1.0" 401 12816 +market-mail.panduit.com - - [08/Mar/2004:13:01:38 -0800] "GET /go/bin/test/TWikiDocGraphics/help.gif HTTP/1.0" 200 130 +64.242.88.10 - - [08/Mar/2004:13:01:42 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=John%20*Talintyre[^A-Za-z] HTTP/1.1" 200 8066 +market-mail.panduit.com - - [08/Mar/2004:13:01:42 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.0" 200 3617 +market-mail.panduit.com - - [08/Mar/2004:13:01:55 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.0" 200 4213 +market-mail.panduit.com - - [08/Mar/2004:13:02:03 -0800] "GET /ops/SP/play//view/Main/VerifingGatway HTTP/1.0" 200 4731 +market-mail.panduit.com - - [08/Mar/2004:13:02:16 -0800] "GET /ops/SP/play//view/Main/Relay_Domains HTTP/1.0" 200 4564 +64.242.88.10 - - [08/Mar/2004:13:04:14 -0800] "GET /ops/SP/play//attach/Main/TWikiGuest HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:07:16 -0800] "GET /ops/SP/play//view/Main/NicholasLee?rev=1.1 HTTP/1.1" 200 4456 +64.242.88.10 - - [08/Mar/2004:13:08:17 -0800] "GET /ops/SP/play//attach/TWiki/TWikiDocGraphics?filename=pencil.gif&revInfo=1 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:12:54 -0800] "GET /ops/SP/play//rdiff/TWiki/WebSiteTools?rev1=1.2&rev2=1.1 HTTP/1.1" 200 6640 +64.242.88.10 - - [08/Mar/2004:13:15:03 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=r1.55 HTTP/1.1" 200 44652 +64.242.88.10 - - [08/Mar/2004:13:16:11 -0800] "GET /ops/SP/play//attach/Main/SpamAssassinAndPostFix HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:17:23 -0800] "GET /mailman/private/artsscience/ HTTP/1.1" 200 1552 +64.242.88.10 - - [08/Mar/2004:13:18:57 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^l HTTP/1.1" 200 2937 +64.242.88.10 - - [08/Mar/2004:13:24:49 -0800] "GET /ops/SP/play//rdiff/Main/RelayGateway?rev1=1.3&rev2=1.2 HTTP/1.1" 200 5181 +64.242.88.10 - - [08/Mar/2004:13:29:37 -0800] "GET /ops/SP/play//rdiff/Main/RelayGateway?rev1=1.2&rev2=1.1 HTTP/1.1" 200 6029 +64.242.88.10 - - [08/Mar/2004:13:31:16 -0800] "GET /ops/SP/play//rdiff/TWiki/WikiReferences?rev1=1.2&rev2=1.1 HTTP/1.1" 200 10024 +64.242.88.10 - - [08/Mar/2004:13:32:35 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=r1.9 HTTP/1.1" 200 7511 +64.242.88.10 - - [08/Mar/2004:13:35:02 -0800] "GET /ops/SP/play//edit/TWiki/WebSiteTools?t=1078731408 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:36:06 -0800] "GET /ops/SP/play//attach/TWiki/TWikiDocGraphics?filename=viewtopic.gif&revInfo=1 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:38:39 -0800] "GET /ops/SP/play//view/TWiki/SvenDowideit?rev=r1.1 HTTP/1.1" 200 3564 +64.242.88.10 - - [08/Mar/2004:13:45:46 -0800] "GET /ops/SP/play//edit/Main/Ignore_mx_lookup_error?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:48:06 -0800] "GET /ops/SP/play//oops/Main/DCCAndPostFix?template=oopsmore¶m1=1.2¶m2=1.2 HTTP/1.1" 200 6602 +64.242.88.10 - - [08/Mar/2004:13:49:47 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=r1.54 HTTP/1.1" 200 44644 +64.242.88.10 - - [08/Mar/2004:13:55:51 -0800] "GET /ops/SP/play//edit/Main/Allow_min_user?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:56:52 -0800] "GET /ops/SP/play//edit/TWiki/KevinKinnell?t=1078692967 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:57:52 -0800] "GET /pipermail/fcd/ HTTP/1.1" 200 468 +64.242.88.10 - - [08/Mar/2004:13:58:55 -0800] "GET /mailman/listinfo/mgt-157 HTTP/1.1" 200 6189 +64.242.88.10 - - [08/Mar/2004:14:00:08 -0800] "GET /mailman/admin/fcd HTTP/1.1" 200 2060 +64.242.88.10 - - [08/Mar/2004:14:01:36 -0800] "GET /mailman/listinfo/cnc_forestry HTTP/1.1" 200 6159 +64.242.88.10 - - [08/Mar/2004:14:07:26 -0800] "GET /ops/SP/play//edit/Main/Strict_8bitmime?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:14:11:28 -0800] "GET /ops/SP/play//view/TWiki/WelcomeGuest?rev=r1.19 HTTP/1.1" 200 13997 +64.242.88.10 - - [08/Mar/2004:14:12:49 -0800] "GET /ops/SP/play//view/TWiki/TWikiFAQ?rev=1.11 HTTP/1.1" 200 11950 +64.242.88.10 - - [08/Mar/2004:14:13:51 -0800] "GET /mailman/admin/gisgrad HTTP/1.1" 200 2093 +64.242.88.10 - - [08/Mar/2004:14:15:01 -0800] "GET /mailman/admin/jjec HTTP/1.1" 200 2088 +fw.aub.dk - - [08/Mar/2004:14:16:38 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +fw.aub.dk - - [08/Mar/2004:14:16:39 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +64.242.88.10 - - [08/Mar/2004:14:23:54 -0800] "GET /ops/SP/play//oops/TWiki/RyanFreebern?template=oopsmore¶m1=1.2¶m2=1.2 HTTP/1.1" 200 11263 +64.242.88.10 - - [08/Mar/2004:14:25:33 -0800] "GET /ops/SP/play//rdiff/TWiki/WebChangesAlert HTTP/1.1" 200 27035 +64.242.88.10 - - [08/Mar/2004:14:26:45 -0800] "GET /ops/SP/play//rdiff/Sandbox/WebTopicList HTTP/1.1" 200 4319 +64.242.88.10 - - [08/Mar/2004:14:27:46 -0800] "GET /ops/SP/play//edit/Main/Virtual_gid_maps?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:14:28:46 -0800] "GET /ops/SP/play//view/TWiki/NewUserTemplate?skin=print HTTP/1.1" 200 2449 +64.242.88.10 - - [08/Mar/2004:14:33:56 -0800] "GET /mailman/admin HTTP/1.1" 200 6872 +64.242.88.10 - - [08/Mar/2004:14:40:18 -0800] "GET /mailman/admin/ncbnpfaculty HTTP/1.1" 200 2136 +64.242.88.10 - - [08/Mar/2004:14:41:22 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Web%20*Topic%20*List[^A-Za-z] HTTP/1.1" 200 10700 +64.242.88.10 - - [08/Mar/2004:14:42:44 -0800] "GET /ops/SP/play//view/TWiki/WebSearch?rev=1.11 HTTP/1.1" 200 9419 +64.242.88.10 - - [08/Mar/2004:14:43:45 -0800] "GET /ops/SP/play//view/TWiki/MartinCleaver HTTP/1.1" 200 3634 +64.242.88.10 - - [08/Mar/2004:14:52:51 -0800] "GET /ops/SP/play//view/TWiki/WebIndex HTTP/1.1" 200 102154 +64.242.88.10 - - [08/Mar/2004:14:54:56 -0800] "GET /ops/SP/play//edit/Main/TokyoOffice?t=1078706364 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:14:57:19 -0800] "GET /ops/SP/play//rdiff/Main/SpamAssassinAndPostFix?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5794 +64.242.88.10 - - [08/Mar/2004:14:58:58 -0800] "GET /ops/SP/play//rdiff/TWiki/WhatIsWikiWiki HTTP/1.1" 200 9412 +64.242.88.10 - - [08/Mar/2004:15:00:07 -0800] "GET /ops/SP/play//rdiff/Main/WebChanges?rev1=1.2&rev2=1.1 HTTP/1.1" 200 114220 +64.242.88.10 - - [08/Mar/2004:15:01:12 -0800] "GET /ops/SP/play//rdiff/TWiki/EditDoesNotIncreaseTheRevision HTTP/1.1" 200 6310 +64.242.88.10 - - [08/Mar/2004:15:02:29 -0800] "GET /ops/SP/play//rdiff/TWiki/WebTopicList HTTP/1.1" 200 14591 +64.242.88.10 - - [08/Mar/2004:15:03:49 -0800] "GET /antivirus.jsp HTTP/1.1" 200 3548 +64.242.88.10 - - [08/Mar/2004:15:07:41 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Harold%20*Gottschalk[^A-Za-z] HTTP/1.1" 200 4412 +ip-200-56-225-61-mty.marcatel.net.mx - - [08/Mar/2004:15:15:17 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +64.242.88.10 - - [08/Mar/2004:15:16:14 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.37 HTTP/1.1" 200 28922 +64.242.88.10 - - [08/Mar/2004:15:17:18 -0800] "GET /ops/SP/play//search/Main/?scope=topic®ex=on&search=^f HTTP/1.1" 200 3438 +64.242.88.10 - - [08/Mar/2004:15:19:35 -0800] "GET /RBL.jsp HTTP/1.1" 200 4114 +c-24-11-14-147.client.comcast.net - - [08/Mar/2004:16:54:47 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +c-24-11-14-147.client.comcast.net - - [08/Mar/2004:16:54:47 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +lj1036.passgo.com - - [08/Mar/2004:17:39:00 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1168.passgo.com - - [08/Mar/2004:17:39:01 -0800] "GET /ops/SP/play//oops/TWiki/TWikiVariables HTTP/1.0" 200 209 +calcite.rhyolite.com - - [08/Mar/2004:18:14:44 -0800] "GET /clients.jsp HTTP/1.1" 200 18767 +acbf6930.ipt.aol.com - - [08/Mar/2004:18:20:44 -0800] "GET /RBL.jsp HTTP/1.1" 200 4114 +acbf6930.ipt.aol.com - - [08/Mar/2004:18:20:44 -0800] "GET /LateEmail.jsp HTTP/1.1" 200 7649 +lj1018.passgo.com - - [08/Mar/2004:18:23:43 -0800] "GET /ops/SP/play//oops/Know/PublicSupported HTTP/1.0" 200 209 +barrie-ppp108371.sympatico.ca - - [08/Mar/2004:18:39:33 -0800] "GET /mailman/listinfo/webber HTTP/1.1" 200 6051 +barrie-ppp108371.sympatico.ca - - [08/Mar/2004:18:39:35 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +barrie-ppp108371.sympatico.ca - - [08/Mar/2004:18:39:35 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +barrie-ppp108371.sympatico.ca - - [08/Mar/2004:18:39:36 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +px7wh.vc.shawcable.net - - [08/Mar/2004:18:41:16 -0800] "GET /LateEmail.jsp HTTP/1.1" 200 7649 +user-0c8hdkf.cable.mindspring.com - - [08/Mar/2004:19:08:27 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +user-0c8hdkf.cable.mindspring.com - - [08/Mar/2004:19:08:28 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +user-0c8hdkf.cable.mindspring.com - - [08/Mar/2004:19:08:39 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.1" 200 4232 +user-0c8hdkf.cable.mindspring.com - - [08/Mar/2004:19:08:52 -0800] "GET /ops/SP/play//view/Main/VerifingGatway HTTP/1.1" 200 4750 +user-0c8hdkf.cable.mindspring.com - - [08/Mar/2004:19:10:06 -0800] "GET /ops/SP/play//view/Main/Relay_Domains HTTP/1.1" 200 4583 +lj1053.passgo.com - - [08/Mar/2004:19:24:42 -0800] "GET /ops/SP/play//oops/Main/SpamAssassinTaggingOnly HTTP/1.0" 200 209 +64.246.94.152 - - [08/Mar/2004:20:09:57 -0800] "HEAD /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 0 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:18 -0800] "GET / HTTP/1.0" 200 3169 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:18 -0800] "GET /favicon.ico HTTP/1.0" 200 1078 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:25 -0800] "GET /ststats/index.jsp HTTP/1.0" 200 2955 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.0" 200 3049 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.0" 200 2160 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.0" 200 2386 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.0" 200 3271 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.0" 200 1687 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.0" 200 2482 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:27 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.0" 200 1914 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:27 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.0" 200 1536 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:27 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.0" 200 2250 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:27 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.0" 200 1883 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:27 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.0" 200 1493 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:48 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:49 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:49 -0800] "GET /favicon.ico HTTP/1.0" 200 1078 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:53 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.0" 200 5234 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:50:59 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.0" 200 4022 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:51:01 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.0" 200 5672 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:51:51 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.0" 200 4062 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:52:01 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.0" 200 4062 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:04 -0800] "GET / HTTP/1.0" 200 3169 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:28 -0800] "GET /ststats/index.jsp HTTP/1.0" 200 2955 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.0" 200 3238 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.0" 200 3032 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.0" 200 2160 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.0" 200 2369 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.0" 200 1671 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.0" 200 2485 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.0" 200 1533 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.0" 200 1906 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.0" 200 2251 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.0" 200 1875 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.0" 200 1483 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:44 -0800] "GET /SpamAssassin.jsp HTTP/1.0" 200 7368 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:52 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +proxy0.haifa.ac.il - - [08/Mar/2004:22:04:09 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +proxy0.haifa.ac.il - - [08/Mar/2004:22:04:10 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +proxy0.haifa.ac.il - - [08/Mar/2004:22:04:24 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.0" 200 4515 +proxy0.haifa.ac.il - - [08/Mar/2004:22:04:35 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.0" 200 4004 +alille-251-1-2-197.w82-124.abo.wanadoo.fr - - [08/Mar/2004:22:30:01 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +a213-84-36-192.adsl.xs4all.nl - - [08/Mar/2004:23:42:55 -0800] "GET / HTTP/1.1" 200 3169 +195.246.13.119 - - [09/Mar/2004:01:48:27 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +195.246.13.119 - - [09/Mar/2004:01:48:28 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +195.246.13.119 - - [09/Mar/2004:01:48:28 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +195.246.13.119 - - [09/Mar/2004:01:49:53 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +195.246.13.119 - - [09/Mar/2004:01:49:57 -0800] "GET /ops/SP/play//view/Main/KevinWGagel HTTP/1.1" 200 4901 +195.246.13.119 - - [09/Mar/2004:01:50:35 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +195.246.13.119 - - [09/Mar/2004:01:50:54 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +195.246.13.119 - - [09/Mar/2004:01:51:17 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +195.246.13.119 - - [09/Mar/2004:01:51:41 -0800] "GET /ops/SP/play//edit/Main/RazorAndPostFix?topicparent=Main.WebHome HTTP/1.1" 401 12851 +195.246.13.119 - - [09/Mar/2004:01:51:45 -0800] "GET /go/bin/test/TWikiDocGraphics/help.gif HTTP/1.1" 200 130 +195.246.13.119 - - [09/Mar/2004:01:51:54 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.1" 200 4232 +195.246.13.119 - - [09/Mar/2004:01:52:12 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.1" 200 4534 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:10 -0800] "GET /ststats/index.jsp HTTP/1.1" 200 2955 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:17 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3068 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:17 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2187 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:17 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3277 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:17 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2379 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1687 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2592 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1983 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1545 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2222 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1866 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1494 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +lj1052.passgo.com - - [09/Mar/2004:02:39:17 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1162.passgo.com - - [09/Mar/2004:02:39:18 -0800] "GET /ops/SP/play//view/Main/SanJoseOffice HTTP/1.0" 200 3884 +lj1162.passgo.com - - [09/Mar/2004:03:10:39 -0800] "GET /ops/SP/play//view/Main/SanJoseOffice HTTP/1.0" 200 3884 +mail.geovariances.fr - - [09/Mar/2004:05:01:53 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +mail.geovariances.fr - - [09/Mar/2004:05:01:53 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +mail.geovariances.fr - - [09/Mar/2004:05:02:11 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.1" 200 4081 +mail.geovariances.fr - - [09/Mar/2004:05:02:11 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:02:14 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +mail.geovariances.fr - - [09/Mar/2004:05:02:14 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:02:19 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +mail.geovariances.fr - - [09/Mar/2004:05:02:19 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:02:27 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +mail.geovariances.fr - - [09/Mar/2004:05:02:28 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:04:09 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +mail.geovariances.fr - - [09/Mar/2004:05:04:09 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:09:30 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +mail.geovariances.fr - - [09/Mar/2004:05:09:31 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:12:45 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:12:45 -0800] "GET /ops/SP/play//view/Main/ConfigurationVariables HTTP/1.1" 200 58292 +mail.geovariances.fr - - [09/Mar/2004:05:13:40 -0800] "GET /ops/SP/play//view/TWiki/WebHome HTTP/1.1" 200 15182 +mail.geovariances.fr - - [09/Mar/2004:05:13:40 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:13:40 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot131x64.gif HTTP/1.1" 200 7218 +mail.geovariances.fr - - [09/Mar/2004:05:13:40 -0800] "GET /go/bin/test/TWikiDocGraphics/tip.gif HTTP/1.1" 200 123 +mail.geovariances.fr - - [09/Mar/2004:05:13:40 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot88x31.gif HTTP/1.1" 200 3501 +mail.geovariances.fr - - [09/Mar/2004:05:14:13 -0800] "GET /ops/SP/play//view/Sandbox/WebHome HTTP/1.1" 200 8632 +mail.geovariances.fr - - [09/Mar/2004:05:14:14 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +66-194-6-70.gen.twtelecom.net - - [09/Mar/2004:05:20:20 -0800] "GET / HTTP/1.1" 200 3169 +195.230.181.122 - - [09/Mar/2004:06:29:03 -0800] "GET /AmavisNew.jsp HTTP/1.0" 200 2300 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:33:21 -0800] "GET / HTTP/1.1" 200 3169 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:51 -0800] "GET /ststats/index.jsp HTTP/1.1" 200 2955 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:53 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3027 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:53 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2148 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:54 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3200 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:54 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2341 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:55 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1686 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:55 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2534 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:56 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1948 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:56 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1549 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:57 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2214 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:57 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1873 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:58 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1500 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:04 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6708 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 8232 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:09 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8857 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:10 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7175 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:13 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9391 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:13 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6922 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:17 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6618 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:17 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5615 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:42 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:36:28 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:36:29 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:36:51 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:37:00 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:37:40 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:10 -0800] "GET / HTTP/1.1" 200 3169 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:10 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:44 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:44 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:44 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:59 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:28:05 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:28:12 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +207.195.59.160 - - [09/Mar/2004:08:08:35 -0800] "GET / HTTP/1.1" 200 3169 +207.195.59.160 - - [09/Mar/2004:08:08:37 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +207.195.59.160 - - [09/Mar/2004:08:08:38 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +207.195.59.160 - - [09/Mar/2004:08:08:54 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +207.195.59.160 - - [09/Mar/2004:08:08:54 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +207.195.59.160 - - [09/Mar/2004:08:08:57 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +207.195.59.160 - - [09/Mar/2004:08:09:39 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.1" 200 4665 +207.195.59.160 - - [09/Mar/2004:08:09:39 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +207.195.59.160 - - [09/Mar/2004:08:09:58 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +207.195.59.160 - - [09/Mar/2004:08:09:58 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +207.195.59.160 - - [09/Mar/2004:08:10:04 -0800] "GET /ops/SP/play//edit/Main/PostConf?topicparent=Main.PostfixCommands HTTP/1.1" 401 12851 +207.195.59.160 - - [09/Mar/2004:08:10:06 -0800] "GET /go/bin/test/TWikiDocGraphics/help.gif HTTP/1.1" 200 130 +207.195.59.160 - - [09/Mar/2004:08:10:12 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.1" 200 4232 +207.195.59.160 - - [09/Mar/2004:08:10:12 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +207.195.59.160 - - [09/Mar/2004:08:10:20 -0800] "GET /ops/SP/play//view/Main/Relay_Domains HTTP/1.1" 200 4583 +fw1.millardref.com - - [09/Mar/2004:08:17:27 -0800] "GET / HTTP/1.1" 200 3169 +207.195.59.160 - - [09/Mar/2004:08:17:34 -0800] "GET /ops/SP/play//view/Main/VerifingGatway HTTP/1.1" 200 4750 +fw1.millardref.com - - [09/Mar/2004:08:17:50 -0800] "GET /RBL.jsp HTTP/1.1" 200 4114 +207.195.59.160 - - [09/Mar/2004:08:18:17 -0800] "GET /ops/SP/play//view/Main/SideBar HTTP/1.1" 200 3972 +207.195.59.160 - - [09/Mar/2004:08:18:17 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +fw1.millardref.com - - [09/Mar/2004:08:18:19 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +fw1.millardref.com - - [09/Mar/2004:08:18:25 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +fw1.millardref.com - - [09/Mar/2004:08:18:26 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +fw1.millardref.com - - [09/Mar/2004:08:18:27 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +fw1.millardref.com - - [09/Mar/2004:08:18:27 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +207.195.59.160 - - [09/Mar/2004:08:18:50 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +207.195.59.160 - - [09/Mar/2004:08:19:04 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +lj1007.passgo.com - - [09/Mar/2004:09:55:44 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1125.passgo.com - - [09/Mar/2004:09:55:53 -0800] "GET /ops/SP/play//oops/TWiki/WebChangesAlert HTTP/1.0" 200 209 +80.58.35.111.proxycache.rima-tde.net - - [09/Mar/2004:10:08:07 -0800] "GET /RBL.jsp HTTP/1.0" 200 4114 +10.0.0.176 - - [09/Mar/2004:10:29:38 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [09/Mar/2004:10:29:40 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8830 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 7255 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6703 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7127 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9241 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6856 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6618 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5615 +200.222.33.33 - - [09/Mar/2004:11:21:36 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +1-320.tnr.on.ca - - [09/Mar/2004:11:43:54 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +1-320.tnr.on.ca - - [09/Mar/2004:11:43:56 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +1-320.tnr.on.ca - - [09/Mar/2004:11:43:56 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +1-320.tnr.on.ca - - [09/Mar/2004:11:43:56 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +l07v-1-17.d1.club-internet.fr - - [09/Mar/2004:11:57:20 -0800] "GET / HTTP/1.1" 200 3169 +wwwcache.lanl.gov - - [09/Mar/2004:12:16:06 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +trrc02m01-40.bctel.ca - - [09/Mar/2004:12:21:08 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +trrc02m01-40.bctel.ca - - [09/Mar/2004:12:21:09 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +trrc02m01-40.bctel.ca - - [09/Mar/2004:12:21:09 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +trrc02m01-40.bctel.ca - - [09/Mar/2004:12:21:10 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +fw.kcm.org - - [09/Mar/2004:12:21:49 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +fw.kcm.org - - [09/Mar/2004:12:21:49 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +lj1048.passgo.com - - [09/Mar/2004:12:52:21 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1031.passgo.com - - [09/Mar/2004:12:52:58 -0800] "GET /ops/SP/play//oops/TWiki/InterwikiPlugin HTTP/1.0" 200 209 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:14:53 -0800] "GET / HTTP/1.1" 200 3169 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:15:15 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:15:15 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:15:23 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.1" 200 4081 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:15:33 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:15:49 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:16:00 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +h194n2fls308o1033.telia.com - - [09/Mar/2004:13:49:05 -0800] "-" 408 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:02 -0800] "GET /mailman HTTP/1.1" 302 301 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:03 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:04 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:05 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:05 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:12 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:15 -0800] "GET / HTTP/1.1" 200 3169 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:23 -0800] "GET /mailman HTTP/1.1" 302 301 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:23 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:24 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:24 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:24 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:28 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:56:15 -0800] "GET / HTTP/1.1" 304 - +home.yeungs.net - - [09/Mar/2004:15:03:55 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +203.147.138.233 - - [09/Mar/2004:15:25:03 -0800] "GET /ststats/index.jsp HTTP/1.1" 200 2955 +203.147.138.233 - - [09/Mar/2004:15:25:05 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +203.147.138.233 - - [09/Mar/2004:15:25:14 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3041 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1695 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2577 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3203 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1970 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2181 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1550 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2314 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1850 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2213 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1509 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:37:35 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:37:36 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:37:36 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:37:36 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:15:44:52 -0800] "GET / HTTP/1.1" 200 3169 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:15:44:52 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:15:44:57 -0800] "GET /rejected.jsp HTTP/1.1" 200 3998 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:51:10 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 2082 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:51:24 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 2182 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:52:09 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 2182 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:52:15 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 19597 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:53:40 -0800] "GET /mailman/admin/ppwc/logout HTTP/1.1" 200 2103 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:53:49 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:53:56 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +lj1123.passgo.com - - [09/Mar/2004:16:23:55 -0800] "GET /ops/SP/play//oops/TWiki/RegularExp HTTP/1.0" 200 209 +206-15-133-153.dialup.ziplink.net - - [09/Mar/2004:16:27:48 -0800] "HEAD /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 0 +lj1048.passgo.com - - [09/Mar/2004:17:10:26 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1061.passgo.com - - [09/Mar/2004:17:10:28 -0800] "GET /ops/SP/play//oops/TWiki/TablePlugin HTTP/1.0" 200 209 +korell2.cc.gatech.edu - - [09/Mar/2004:17:33:58 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +65-37-13-251.nrp2.roc.ny.frontiernet.net - - [09/Mar/2004:17:42:41 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +65-37-13-251.nrp2.roc.ny.frontiernet.net - - [09/Mar/2004:17:42:42 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +65-37-13-251.nrp2.roc.ny.frontiernet.net - - [09/Mar/2004:17:42:42 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +65-37-13-251.nrp2.roc.ny.frontiernet.net - - [09/Mar/2004:17:43:54 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.1" 200 4665 +65-37-13-251.nrp2.roc.ny.frontiernet.net - - [09/Mar/2004:17:45:02 -0800] "GET /ops/SP/play//view/Sandbox/WebHome HTTP/1.1" 200 8632 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:00:43 -0800] "GET /mailman/admin HTTP/1.1" 200 6872 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:00:44 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:00:44 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:00:44 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:01:11 -0800] "GET /mailman/admin/webct HTTP/1.1" 200 2080 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:01:24 -0800] "GET /mailman HTTP/1.1" 302 301 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:01:25 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:01:28 -0800] "GET /mailman/listinfo/administration HTTP/1.1" 200 6459 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:01:45 -0800] "GET /mailman/listinfo/cnc_notice HTTP/1.1" 200 6337 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:02:07 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +grandpa.mmlc.northwestern.edu - - [09/Mar/2004:18:06:27 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +grandpa.mmlc.northwestern.edu - - [09/Mar/2004:18:06:27 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:23:32 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:23:32 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:25:15 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:25:18 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +calcite.rhyolite.com - - [09/Mar/2004:20:34:55 -0800] "GET /clients.jsp HTTP/1.1" 200 18892 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:45:43 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:45:48 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:45:51 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +2-238.tnr.on.ca - - [09/Mar/2004:21:33:22 -0800] "GET / HTTP/1.1" 200 3169 +lj1048.passgo.com - - [09/Mar/2004:21:51:09 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1153.passgo.com - - [09/Mar/2004:21:51:16 -0800] "GET /ops/SP/play//oops/Main/ThanadonSomdee HTTP/1.0" 200 209 +mmscrm07-2.uah.goweb.net - - [09/Mar/2004:22:23:39 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1036.passgo.com - - [09/Mar/2004:22:31:21 -0800] "GET /ops/SP/play//oops/Know/TopicClassification HTTP/1.0" 200 209 +adsl-157-26-153.msy.bellsouth.net - - [09/Mar/2004:22:40:32 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +adsl-157-26-153.msy.bellsouth.net - - [09/Mar/2004:22:40:33 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +lj1164.passgo.com - - [09/Mar/2004:22:44:31 -0800] "GET /ops/SP/play//oops/TWiki/TextFormattingRules HTTP/1.0" 200 209 +66-194-6-79.gen.twtelecom.net - - [09/Mar/2004:23:36:11 -0800] "GET / HTTP/1.1" 200 3169 +lj1231.passgo.com - - [10/Mar/2004:00:21:51 -0800] "GET /ops/SP/play//oops/Main/TWikiUsers HTTP/1.0" 200 209 +212.21.228.26 - - [10/Mar/2004:00:24:58 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +yongsan-cache.korea.army.mil - - [10/Mar/2004:00:29:44 -0800] "GET /mailman/listinfo/cncce HTTP/1.1" 200 6208 +yongsan-cache.korea.army.mil - - [10/Mar/2004:00:29:44 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +yongsan-cache.korea.army.mil - - [10/Mar/2004:00:29:44 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +yongsan-cache.korea.army.mil - - [10/Mar/2004:00:29:45 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +pd9e761cf.dip.t-dialin.net - - [10/Mar/2004:02:07:27 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +lj1048.passgo.com - - [10/Mar/2004:02:31:33 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1160.passgo.com - - [10/Mar/2004:02:31:44 -0800] "GET /razor.jsp HTTP/1.0" 304 - +nb-bolz.cremona.polimi.it - - [10/Mar/2004:02:52:49 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +pc-030-040.eco.rug.nl - - [10/Mar/2004:02:55:00 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:11:40 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:11:50 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:11:53 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:07 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:20 -0800] "GET /ops/SP/play//view/Main/ConfigurationVariables HTTP/1.1" 200 58292 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:33 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.1" 200 4665 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:45 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:48 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.1" 200 3629 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:56 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.1" 200 4534 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:14:40 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:14:54 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:15:28 -0800] "GET /ops/SP/play//view/Main/SideBar HTTP/1.1" 200 3972 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:15:33 -0800] "GET /ops/SP/play//view/Main/DCCGraphs HTTP/1.1" 200 5402 +80.58.14.235.proxycache.rima-tde.net - - [10/Mar/2004:03:52:49 -0800] "GET /mailman/listinfo/fnac HTTP/1.0" 200 5969 +80.58.14.235.proxycache.rima-tde.net - - [10/Mar/2004:03:52:51 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +80.58.14.235.proxycache.rima-tde.net - - [10/Mar/2004:03:52:51 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +80.58.14.235.proxycache.rima-tde.net - - [10/Mar/2004:03:52:52 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +66-194-6-70.gen.twtelecom.net - - [10/Mar/2004:05:21:38 -0800] "GET / HTTP/1.1" 200 3169 +pd9e50809.dip.t-dialin.net - - [10/Mar/2004:07:36:56 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +10.0.0.176 - - [10/Mar/2004:08:36:28 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:08:36:30 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 7783 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8845 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6274 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7071 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9328 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6976 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +10.0.0.176 - - [10/Mar/2004:08:36:57 -0800] "GET /ststats/index.jsp HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3020 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2287 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2332 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1673 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2583 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1976 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3364 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2220 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1627 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1837 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1528 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:51:31 -0800] "GET / HTTP/1.1" 304 - +ts05-ip44.hevanet.com - - [10/Mar/2004:08:52:13 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:52:16 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ts05-ip44.hevanet.com - - [10/Mar/2004:08:52:25 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:52:52 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:53:12 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:53:19 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.1" 200 4173 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:53:33 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.1" 200 3629 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:54:15 -0800] "GET /ops/SP/play//view/Main/ConfigurationVariables HTTP/1.1" 200 58292 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:54:37 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.1" 200 4665 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:55:03 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.1" 200 4232 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:55:17 -0800] "GET /ops/SP/play//view/Main/VerifingGatway HTTP/1.1" 200 4750 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:55:40 -0800] "GET /ops/SP/play//view/Main/KevinWGagel HTTP/1.1" 200 4901 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:55:49 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.1" 200 4534 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:56:10 -0800] "GET /ops/SP/play//view/Main/SideBar HTTP/1.1" 200 3972 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:56:13 -0800] "GET /ops/SP/play//view/Main/DCCGraphs HTTP/1.1" 200 5402 +lj1048.passgo.com - - [10/Mar/2004:09:05:59 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1145.passgo.com - - [10/Mar/2004:09:05:59 -0800] "GET /ops/SP/play//oops/TWiki/MoveTopic HTTP/1.0" 200 209 +cacher2-ext.wise.edt.ericsson.se - - [10/Mar/2004:09:41:56 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +adsl-64-173-42-65.dsl.snfc21.pacbell.net - - [10/Mar/2004:10:37:53 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +ic8234.upco.es - - [10/Mar/2004:10:38:04 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +ic8234.upco.es - - [10/Mar/2004:10:38:05 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +ic8234.upco.es - - [10/Mar/2004:10:38:23 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +ic8234.upco.es - - [10/Mar/2004:10:38:27 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.1" 200 3629 +ns.mou.cz - - [10/Mar/2004:10:59:06 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:12:51 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +lj1117.passgo.com - - [10/Mar/2004:11:13:21 -0800] "GET /ops/SP/play//view/Know/WebStatistics HTTP/1.0" 200 6394 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:18:59 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 2082 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:19:00 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:19:00 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:19:00 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:19:32 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 19597 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:41:25 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 2082 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:41:25 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:41:25 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:41:25 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:41:52 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 19597 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:43:26 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:44:13 -0800] "GET /mailman/admin/ppwc/members HTTP/1.1" 200 15271 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:44:27 -0800] "GET /mailman/admin/ppwc/members?letter=n HTTP/1.1" 200 15131 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:44:44 -0800] "GET /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 24507 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:45:22 -0800] "GET /mailman/admin/ppwc/passwords HTTP/1.1" 200 6217 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:45:51 -0800] "GET /mailman/admin/ppwc/gateway HTTP/1.1" 200 0 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:45:51 -0800] "GET /mailman/admin/ppwc/gateway HTTP/1.1" 200 8692 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:46:42 -0800] "GET /mailman/admin/ppwc/general HTTP/1.1" 200 19597 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:47:37 -0800] "GET /mailman/admin/ppwc/?VARHELP=general/owner HTTP/1.1" 200 3505 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:49:57 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 2082 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:49:57 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:49:57 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:49:57 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:50:28 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:50:35 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:52:14 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:52:42 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +10.0.0.176 - - [10/Mar/2004:12:02:38 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:43 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +10.0.0.176 - - [10/Mar/2004:12:02:43 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:45 -0800] "GET /mailman HTTP/1.1" 302 301 +10.0.0.176 - - [10/Mar/2004:12:02:46 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +10.0.0.176 - - [10/Mar/2004:12:02:46 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:46 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:46 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:50 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +10.0.0.176 - - [10/Mar/2004:12:02:50 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:50 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:50 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:52 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 2082 +10.0.0.176 - - [10/Mar/2004:12:02:52 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:52 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:52 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:59 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 19597 +10.0.0.176 - - [10/Mar/2004:12:03:00 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:00 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:00 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:03 -0800] "GET /mailman/admin/ppwc/members HTTP/1.1" 200 15271 +10.0.0.176 - - [10/Mar/2004:12:03:04 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:04 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:04 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:08 -0800] "GET /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 24507 +10.0.0.176 - - [10/Mar/2004:12:03:08 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:08 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:08 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:45 -0800] "GET /mailman/options/ppwc/ppwctwentynine--at--shaw.com HTTP/1.1" 200 14296 +10.0.0.176 - - [10/Mar/2004:12:03:45 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:45 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:45 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:06 -0800] "POST /mailman/options/ppwc/ppwctwentynine@shaw.com HTTP/1.1" 200 14579 +10.0.0.176 - - [10/Mar/2004:12:05:06 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:06 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:06 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:22 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 19597 +10.0.0.176 - - [10/Mar/2004:12:05:22 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:22 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:22 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:38 -0800] "GET /mailman/admin/ppwc/members HTTP/1.1" 200 15271 +10.0.0.176 - - [10/Mar/2004:12:05:38 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:38 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:38 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:40 -0800] "GET /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 24525 +10.0.0.176 - - [10/Mar/2004:12:05:40 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:40 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:40 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:54 -0800] "POST /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 23169 +10.0.0.176 - - [10/Mar/2004:12:05:54 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:54 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:54 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:58 -0800] "GET /mailman/admin/ppwc/general HTTP/1.1" 200 19597 +10.0.0.176 - - [10/Mar/2004:12:05:58 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:58 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:58 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:07 -0800] "GET /mailman/admin/ppwc/members HTTP/1.1" 200 15271 +10.0.0.176 - - [10/Mar/2004:12:06:07 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:07 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:07 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:09 -0800] "GET /mailman/admin/ppwc/members/add HTTP/1.1" 200 6681 +10.0.0.176 - - [10/Mar/2004:12:06:09 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:09 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:09 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:07 -0800] "POST /mailman/admin/ppwc/members/add HTTP/1.1" 200 6762 +10.0.0.176 - - [10/Mar/2004:12:07:07 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:07 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:08 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:12 -0800] "GET /mailman/admin/ppwc/members/list HTTP/1.1" 200 15271 +10.0.0.176 - - [10/Mar/2004:12:07:12 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:12 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:13 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:14 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:14 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:14 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:14 -0800] "GET /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 24585 +10.0.0.176 - - [10/Mar/2004:12:07:25 -0800] "POST /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 24577 +10.0.0.176 - - [10/Mar/2004:12:07:25 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:25 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:25 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:16:59 -0800] "GET /mailman/admin/ppwc/logout HTTP/1.1" 200 2103 +10.0.0.176 - - [10/Mar/2004:12:16:59 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:16:59 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:16:59 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +142.27.64.35 - - [10/Mar/2004:12:19:02 -0800] "GET / HTTP/1.1" 304 - +142.27.64.35 - - [10/Mar/2004:12:19:05 -0800] "GET /mailman HTTP/1.1" 302 301 +142.27.64.35 - - [10/Mar/2004:12:19:05 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +142.27.64.35 - - [10/Mar/2004:12:19:06 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +142.27.64.35 - - [10/Mar/2004:12:19:06 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +142.27.64.35 - - [10/Mar/2004:12:19:06 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +142.27.64.35 - - [10/Mar/2004:12:19:08 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +lj1216.passgo.com - - [10/Mar/2004:12:22:32 -0800] "GET /ops/SP/play//oops/TWiki/WikiTopic HTTP/1.0" 200 209 +10.0.0.176 - - [10/Mar/2004:12:25:25 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:25:28 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 8663 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6392 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7133 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 9449 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6895 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9403 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +c-411472d5.04-138-73746f22.cust.bredbandsbolaget.se - - [10/Mar/2004:13:13:23 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +3_343_lt_someone - - [10/Mar/2004:13:15:44 -0800] "GET / HTTP/1.1" 200 3169 +3_343_lt_someone - - [10/Mar/2004:13:15:53 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7142 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 5882 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6485 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8673 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6895 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9403 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +watchguard.cgmatane.qc.ca - - [10/Mar/2004:13:41:37 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +watchguard.cgmatane.qc.ca - - [10/Mar/2004:13:42:23 -0800] "GET /RBL.jsp HTTP/1.1" 200 4114 +ppp2.p33.is.com.ua - - [10/Mar/2004:14:20:51 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +ppp2.p33.is.com.ua - - [10/Mar/2004:14:21:36 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +ppp2.p33.is.com.ua - - [10/Mar/2004:14:22:13 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +10.0.0.176 - - [10/Mar/2004:15:06:20 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:15:06:24 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [10/Mar/2004:15:06:24 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 5871 +10.0.0.176 - - [10/Mar/2004:15:06:24 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6484 +10.0.0.176 - - [10/Mar/2004:15:06:24 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7014 +10.0.0.176 - - [10/Mar/2004:15:06:24 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8821 +10.0.0.176 - - [10/Mar/2004:15:06:25 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9306 +10.0.0.176 - - [10/Mar/2004:15:06:25 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6937 +10.0.0.176 - - [10/Mar/2004:15:06:25 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +10.0.0.176 - - [10/Mar/2004:15:06:25 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +lj1024.passgo.com - - [10/Mar/2004:15:10:10 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1028.passgo.com - - [10/Mar/2004:15:10:13 -0800] "GET /ops/SP/play//oops/Main/T HTTP/1.0" 200 209 +lj1145.passgo.com - - [10/Mar/2004:15:49:55 -0800] "GET /ops/SP/play//oops/TWiki/NicholasLee HTTP/1.0" 200 209 +h24-68-45-227.gv.shawcable.net - - [10/Mar/2004:16:29:30 -0800] "GET /pipermail/cnc_notice/2004-February.txt HTTP/1.1" 200 6712 +64.246.94.141 - - [10/Mar/2004:16:31:19 -0800] "HEAD /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 0 +pntn02m05-129.bctel.ca - - [10/Mar/2004:16:33:04 -0800] "GET /pipermail/cncce/2004-January/000001.jsp HTTP/1.1" 200 3095 +calcite.rhyolite.com - - [10/Mar/2004:16:47:44 -0800] "GET /clients.jsp HTTP/1.1" 200 18971 +h24-68-45-227.gv.shawcable.net - - [10/Mar/2004:16:52:44 -0800] "GET /pipermail/cnc_notice/2003-December.txt HTTP/1.1" 200 6570 +h24-68-45-227.gv.shawcable.net - - [10/Mar/2004:16:54:36 -0800] "GET /pipermail/cnc_notice/2003-December/000002.jsp HTTP/1.1" 200 7074 +lj1117.passgo.com - - [10/Mar/2004:18:13:54 -0800] "GET /ops/SP/play//view/Main/VishaalGolam HTTP/1.0" 200 4577 +lj1073.passgo.com - - [10/Mar/2004:18:17:24 -0800] "GET /ops/SP/play//oops/TWiki/Wik HTTP/1.0" 200 209 +lj1024.passgo.com - - [10/Mar/2004:19:55:54 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1000.passgo.com - - [10/Mar/2004:19:55:56 -0800] "GET /ops/SP/play//view/Know/WebHome HTTP/1.0" 200 7529 +dialup-5-81.tulane.edu - - [10/Mar/2004:20:22:41 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +dialup-5-81.tulane.edu - - [10/Mar/2004:20:22:42 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +dialup-5-81.tulane.edu - - [10/Mar/2004:20:23:11 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +dialup-5-81.tulane.edu - - [10/Mar/2004:20:23:41 -0800] "GET /ops/SP/play//view/Main/TWikiGroups HTTP/1.1" 200 4816 +dialup-5-81.tulane.edu - - [10/Mar/2004:20:23:52 -0800] "GET /ops/SP/play//view/Main/TWikiAdminGroup HTTP/1.1" 200 4175 +lj1145.passgo.com - - [10/Mar/2004:21:56:34 -0800] "GET /ops/SP/play//oops/Main/WebStatistics HTTP/1.0" 200 209 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:58:46 -0800] "GET / HTTP/1.1" 200 3169 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:58:46 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:16 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:17 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 5664 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:17 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6403 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8837 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6980 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9241 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6970 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:03 -0800] "GET /ststats/index.jsp HTTP/1.1" 200 2955 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:04 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3093 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2255 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3419 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2381 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1658 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2657 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 2008 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1598 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2223 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1924 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1550 +lj1220.passgo.com - - [10/Mar/2004:22:16:58 -0800] "GET /ops/SP/play//oops/TWiki/SvenDowideit HTTP/1.0" 200 209 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:28 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:30 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 5805 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:30 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6445 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:30 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8809 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6882 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9241 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6970 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +lj1024.passgo.com - - [11/Mar/2004:00:07:57 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1117.passgo.com - - [11/Mar/2004:00:07:58 -0800] "GET /ops/SP/play//oops/Know/WebStatistics HTTP/1.0" 200 209 +lj1120.passgo.com - - [11/Mar/2004:00:42:01 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.0" 200 5234 +ns3.vonroll.ch - - [11/Mar/2004:00:43:57 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +ns3.vonroll.ch - - [11/Mar/2004:00:43:59 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +ns3.vonroll.ch - - [11/Mar/2004:00:44:08 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.0" 200 4646 +lj1145.passgo.com - - [11/Mar/2004:01:39:53 -0800] "GET /ops/SP/play//view/Main/SimonMudd HTTP/1.0" 200 4612 +1513.cps.virtua.com.br - - [11/Mar/2004:02:27:39 -0800] "GET /pipermail/cipg/2003-november.txt HTTP/1.1" 404 309 +194.151.73.43 - - [11/Mar/2004:03:35:49 -0800] "GET /ie.htm HTTP/1.0" 200 3518 +194.151.73.43 - - [11/Mar/2004:03:35:57 -0800] "GET /images/image004.jpg HTTP/1.0" 200 10936 +194.151.73.43 - - [11/Mar/2004:03:35:57 -0800] "GET /images/image005.jpg HTTP/1.0" 200 21125 +194.151.73.43 - - [11/Mar/2004:03:35:58 -0800] "GET /images/msgops.JPG HTTP/1.0" 200 7939 +spica.ukc.ac.uk - - [11/Mar/2004:03:50:09 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +spica.ukc.ac.uk - - [11/Mar/2004:03:50:09 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +ogw.netinfo.nl - - [11/Mar/2004:06:11:19 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +ogw.netinfo.nl - - [11/Mar/2004:06:11:21 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +ogw.netinfo.nl - - [11/Mar/2004:06:11:38 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +ogw.netinfo.nl - - [11/Mar/2004:06:11:39 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:06:11:46 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.1" 200 4173 +ogw.netinfo.nl - - [11/Mar/2004:06:11:47 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:06:12:41 -0800] "GET /ops/SP/play//view/Main/PostQueue HTTP/1.1" 200 4280 +ogw.netinfo.nl - - [11/Mar/2004:06:12:43 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:06:13:07 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.1" 200 3629 +ogw.netinfo.nl - - [11/Mar/2004:06:13:08 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:06:14:03 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.1" 200 4665 +ogw.netinfo.nl - - [11/Mar/2004:06:14:04 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:06:16:40 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.1" 200 4232 +ogw.netinfo.nl - - [11/Mar/2004:06:17:06 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.1" 200 4534 +ogw.netinfo.nl - - [11/Mar/2004:06:17:11 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +lj1024.passgo.com - - [11/Mar/2004:06:27:31 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1153.passgo.com - - [11/Mar/2004:06:27:36 -0800] "GET /ops/SP/play//oops/Sandbox/WebStatistics HTTP/1.0" 200 209 +208-186-146-13.nrp3.brv.mn.frontiernet.net - - [11/Mar/2004:06:48:05 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +208-186-146-13.nrp3.brv.mn.frontiernet.net - - [11/Mar/2004:06:48:05 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +ladybug.cns.vt.edu - - [11/Mar/2004:07:15:10 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +ladybug.cns.vt.edu - - [11/Mar/2004:07:15:11 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +ladybug.cns.vt.edu - - [11/Mar/2004:07:19:57 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +ladybug.cns.vt.edu - - [11/Mar/2004:07:20:05 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +ladybug.cns.vt.edu - - [11/Mar/2004:07:20:09 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +osdlab.eic.nctu.edu.tw - - [11/Mar/2004:07:39:30 -0800] "GET /M83A HTTP/1.0" 404 269 +208.247.148.12 - - [11/Mar/2004:08:14:18 -0800] "GET /mailman/listinfo/ppwc HTTP/1.0" 200 6252 +208.247.148.12 - - [11/Mar/2004:08:14:18 -0800] "GET /icons/mailman.jpg HTTP/1.0" 200 2022 +208.247.148.12 - - [11/Mar/2004:08:14:18 -0800] "GET /icons/PythonPowered.png HTTP/1.0" 200 945 +208.247.148.12 - - [11/Mar/2004:08:14:18 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.0" 200 3049 +ogw.netinfo.nl - - [11/Mar/2004:08:45:41 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +ogw.netinfo.nl - - [11/Mar/2004:08:45:42 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:08:45:49 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +ogw.netinfo.nl - - [11/Mar/2004:08:45:54 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +0x503e4fce.virnxx2.adsl-dhcp.tele.dk - - [11/Mar/2004:10:55:40 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +0x503e4fce.virnxx2.adsl-dhcp.tele.dk - - [11/Mar/2004:10:58:16 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +0x503e4fce.virnxx2.adsl-dhcp.tele.dk - - [11/Mar/2004:10:58:27 -0800] "GET /razor.jsp HTTP/1.1" 304 - +64-93-34-186.client.dsl.net - - [11/Mar/2004:11:12:40 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +d207-6-50-215.bchsia.telus.net - - [11/Mar/2004:11:33:35 -0800] "GET /pipermail/cncce/2004-January/000001.jsp HTTP/1.1" 200 3095 +10.0.0.176 - - [11/Mar/2004:11:49:51 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [11/Mar/2004:11:49:53 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 5622 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6357 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8728 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6791 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9561 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 7087 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6427 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5598 +1-729.tnr.on.ca - - [11/Mar/2004:11:54:59 -0800] "GET / HTTP/1.1" 200 3169 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:22 -0800] "GET /mailman HTTP/1.1" 302 301 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:22 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:22 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:23 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:23 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:26 -0800] "GET /mailman/listinfo/administration HTTP/1.1" 200 6459 +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:28:50 -0800] "GET /mailman/admindb/ppwc HTTP/1.1" 200 2072 +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:28:50 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:28:51 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:28:51 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:29:03 -0800] "POST /mailman/admindb/ppwc HTTP/1.1" 200 3407 +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:29:27 -0800] "POST /mailman/admindb/ppwc HTTP/1.1" 200 1134 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:56:35 -0800] "GET /robots.txt HTTP/1.0" 200 68 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:56:58 -0800] "GET /ops/SP/play//view/TWiki/WebStatistics HTTP/1.0" 200 8193 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:57:18 -0800] "GET /ops/SP/play//view/Main/TWikiGuest HTTP/1.0" 200 4430 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:57:24 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=1.25 HTTP/1.0" 200 9812 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:57:45 -0800] "GET /ops/SP/play//view/Main/WebNotify?rev=r1.6 HTTP/1.0" 200 4300 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:58:03 -0800] "GET /ops/SP/play//rdiff/TWiki/ManagingTopics?rev1=1.16&rev2=1.15 HTTP/1.0" 200 7912 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:58:37 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=r1.8 HTTP/1.0" 200 8986 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:58:50 -0800] "GET /ops/SP/play//edit/Main/Max_idle?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:59:07 -0800] "GET /ops/SP/play//view/Main/WebChanges HTTP/1.0" 200 40430 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:59:33 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Appendix%20*File%20*System%5B%5EA-Za-z%5D HTTP/1.0" 200 5794 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:59:52 -0800] "GET /ops/SP/play//oops/TWiki/AppendixFileSystem?template=oopsmore¶m1=1.12¶m2=1.12 HTTP/1.0" 200 11355 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:00:12 -0800] "GET /ops/SP/play//view/TWiki/WebTopicViewTemplate HTTP/1.0" 200 5420 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:00:47 -0800] "GET /ops/SP/play//rdiff/Main/WebHome HTTP/1.0" 200 69197 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:00:57 -0800] "GET /ops/SP/play//view/TWiki/WebPreferences?rev=r1.9 HTTP/1.0" 200 7875 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:01:21 -0800] "GET /ops/SP/play//rdiff/Main/ConfigurationVariables?rev1=1.2&rev2=1.1 HTTP/1.0" 200 59549 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:01:37 -0800] "GET /ops/SP/play//view/Main/AndreaSterbini HTTP/1.0" 200 3891 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:01:58 -0800] "GET /ops/SP/play//rdiff/Main/AndreaSterbini HTTP/1.0" 200 5567 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:02:22 -0800] "GET /ops/SP/play//rdiff/TWiki/WebNotify HTTP/1.0" 200 11733 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:02:42 -0800] "GET /ops/SP/play//rdiff/Main/WebHome?rev1=1.28&rev2=1.27 HTTP/1.0" 200 3577 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:03:06 -0800] "GET /ops/SP/play//view/Main/WebHome?skin=print HTTP/1.0" 200 8347 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:03:23 -0800] "GET /ops/SP/play//search/Main/SearchResult?search=%5C.*&scope=topic&order=modified&reverse=on®ex=on&nosearch=on HTTP/1.0" 200 43816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:03:48 -0800] "GET /ops/SP/play//view/TWiki/FormattedSearch HTTP/1.0" 200 20420 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:04:09 -0800] "GET /ops/SP/play//oops/Main/WebHome?template=oopsmore¶m1=1.28¶m2=1.8 HTTP/1.0" 200 7410 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:04:30 -0800] "GET /ops/SP/play//edit/TWiki/TextFormattingFAQ?t=1075982736 HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:04:52 -0800] "GET /ops/SP/play//edit/Main/Allow_untrusted_routing?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:05:13 -0800] "GET /ops/SP/play//edit/Main/Smtp_data_init_timeout?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:05:33 -0800] "GET /ops/SP/play//view/TWiki/AppendixFileSystem?rev=1.10 HTTP/1.0" 200 34910 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:05:54 -0800] "GET /ops/SP/play//view/Main/AndreaSterbini?rev=r1.1 HTTP/1.0" 200 3732 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:06:17 -0800] "GET /ops/SP/play//view/Know/WebNotify HTTP/1.0" 200 4472 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:06:39 -0800] "GET /ops/SP/play//rdiff/Main/PeterThoeny HTTP/1.0" 200 18859 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:07:02 -0800] "GET /ops/SP/play//view/Main/WebHome?skin=print&rev=1.25 HTTP/1.0" 200 7762 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:07:20 -0800] "GET /ops/SP/play//edit/Main/Relayhost?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:07:40 -0800] "GET /ops/SP/play//edit/Main/Unknown_virtual_mailbox_reject_code?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:08:03 -0800] "GET /ops/SP/play//view/TWiki/WebPreferences HTTP/1.0" 200 9109 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:08:44 -0800] "GET /ops/SP/play//view/Main/DCC HTTP/1.0" 200 4377 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:09:04 -0800] "GET /ops/SP/play//view/Know/WebHome HTTP/1.0" 200 7529 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:09:21 -0800] "GET /ops/SP/play//view/Main/WebNotify HTTP/1.0" 200 4449 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:09:24 -0800] "GET /ops/SP/play//oops/Main/WebHome?template=oopsmore¶m1=1.28¶m2=1.28 HTTP/1.0" 200 7411 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:09:52 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.0" 200 4004 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:10:11 -0800] "GET /ops/SP/play//view/TWiki/WebHome HTTP/1.0" 200 15147 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:10:27 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.0" 200 4646 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:10:52 -0800] "GET /ops/SP/play//view/Main/WebTopicList HTTP/1.0" 200 7461 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:11:09 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=1.27 HTTP/1.0" 200 10313 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:11:41 -0800] "GET /ops/SP/play//view/Main/ConfigurationVariables HTTP/1.0" 200 58169 +4.37.97.186 - - [11/Mar/2004:13:12:54 -0800] "GET /pipermail/webber/2004-January/000000.jsp HTTP/1.1" 200 2446 +12.22.207.235 - - [11/Mar/2004:13:18:15 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +archserve.id.ucsb.edu - - [11/Mar/2004:13:22:32 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +archserve.id.ucsb.edu - - [11/Mar/2004:13:22:32 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +2-110.tnr.on.ca - - [11/Mar/2004:13:24:03 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +2-110.tnr.on.ca - - [11/Mar/2004:13:24:04 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +2-110.tnr.on.ca - - [11/Mar/2004:13:24:04 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +2-110.tnr.on.ca - - [11/Mar/2004:13:24:04 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +2-110.tnr.on.ca - - [11/Mar/2004:13:26:38 -0800] "GET /images/image005.jpg HTTP/1.1" 304 - +2-110.tnr.on.ca - - [11/Mar/2004:13:26:38 -0800] "GET /images/image004.jpg HTTP/1.1" 304 - +2-110.tnr.on.ca - - [11/Mar/2004:13:26:38 -0800] "GET /images/msgops.JPG HTTP/1.1" 304 - +lj1024.passgo.com - - [11/Mar/2004:13:27:05 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1212.passgo.com - - [11/Mar/2004:13:27:05 -0800] "GET / HTTP/1.0" 200 3169 +2-110.tnr.on.ca - - [11/Mar/2004:14:14:44 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +2-110.tnr.on.ca - - [11/Mar/2004:14:14:47 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +2-110.tnr.on.ca - - [11/Mar/2004:14:14:47 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +2-110.tnr.on.ca - - [11/Mar/2004:14:14:50 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +favr.go.de - - [11/Mar/2004:14:22:08 -0800] "GET /robots.txt HTTP/1.0" 200 68 +favr.go.de - - [11/Mar/2004:14:22:09 -0800] "GET /ops/SP/play//view/Main/WebSearch HTTP/1.0" 200 9263 +favr.go.de - - [11/Mar/2004:14:26:26 -0800] "GET /ops/SP/play//view/Sandbox/WebHome HTTP/1.0" 200 8605 +favr.go.de - - [11/Mar/2004:14:28:53 -0800] "GET /ops/SP/play//view/Sandbox/WebChanges HTTP/1.0" 200 9622 +favr.go.de - - [11/Mar/2004:14:29:44 -0800] "GET /ops/SP/play//view/Sandbox/WebPreferences HTTP/1.0" 200 8380 +favr.go.de - - [11/Mar/2004:14:29:52 -0800] "GET /ops/SP/play//view/Main/WebStatistics HTTP/1.0" 200 8331 +favr.go.de - - [11/Mar/2004:14:30:51 -0800] "GET /ops/SP/play//view/Main/WebTopicList HTTP/1.0" 200 7461 +favr.go.de - - [11/Mar/2004:14:31:43 -0800] "GET /ops/SP/play//view/Main/WebPreferences HTTP/1.0" 200 8793 +lj1008.passgo.com - - [11/Mar/2004:14:31:48 -0800] "GET /ops/SP/play//oops/TWiki/WikiWikiClones HTTP/1.0" 200 209 +favr.go.de - - [11/Mar/2004:14:33:01 -0800] "GET /ops/SP/play//view/Main/WebNotify HTTP/1.0" 200 4449 +64-249-27-114.client.dsl.net - - [11/Mar/2004:14:53:12 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +pd9eb1396.dip.t-dialin.net - - [11/Mar/2004:15:17:08 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +10.0.0.176 - - [11/Mar/2004:15:51:49 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [11/Mar/2004:15:52:07 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +10.0.0.176 - - [11/Mar/2004:15:52:07 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +10.0.0.176 - - [11/Mar/2004:15:52:12 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +10.0.0.176 - - [11/Mar/2004:15:52:12 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +10.0.0.176 - - [11/Mar/2004:15:52:18 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 6329 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8771 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6340 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6846 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9523 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6996 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6427 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5598 +10.0.0.176 - - [11/Mar/2004:15:52:37 -0800] "GET /ststats/index.jsp HTTP/1.1" 304 - +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3241 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3327 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2434 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1676 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 2029 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1604 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2640 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2251 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1899 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1556 +10.0.0.176 - - [11/Mar/2004:15:52:39 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2243 +lj1105.passgo.com - - [11/Mar/2004:16:02:37 -0800] "GET /ops/SP/play//oops/TWiki/1000 HTTP/1.0" 200 209 +wc01.piwa.pow.fr - - [11/Mar/2004:16:12:59 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +wc01.piwa.pow.fr - - [11/Mar/2004:16:13:02 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +wc01.piwa.pow.fr - - [11/Mar/2004:16:13:02 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +wc03.mtnk.rnc.net.cable.rogers.com - - [11/Mar/2004:16:13:03 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +206-15-133-154.dialup.ziplink.net - - [11/Mar/2004:16:33:23 -0800] "HEAD /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 0 +lj1024.passgo.com - - [11/Mar/2004:18:11:39 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1008.passgo.com - - [11/Mar/2004:18:11:40 -0800] "GET /ops/SP/play//oops/Main/Smtpd_recipient_limit HTTP/1.0" 200 209 +ipcorp-c8b07af1.terraempresas.com.br - - [11/Mar/2004:18:31:35 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +66-194-6-79.gen.twtelecom.net - - [11/Mar/2004:18:57:52 -0800] "GET / HTTP/1.1" 200 3169 +lj1223.passgo.com - - [11/Mar/2004:20:12:24 -0800] "GET /ops/SP/play//view/Main/MikeMannix HTTP/1.0" 200 3674 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:32 -0800] "GET /ststats/ HTTP/1.1" 200 2955 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:37 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3091 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:37 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2230 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:37 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2388 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:37 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3440 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1659 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2662 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 2064 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1624 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2243 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1879 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1575 +lj1073.passgo.com - - [11/Mar/2004:20:59:05 -0800] "GET /ops/SP/play//oops/TWiki/TWikiPlannedFeatures HTTP/1.0" 200 209 +mmscrm07-2.uah.goweb.net - - [11/Mar/2004:23:56:31 -0800] "GET /robots.txt HTTP/1.0" 200 68 +66-194-6-71.gen.twtelecom.net - - [12/Mar/2004:01:30:44 -0800] "GET / HTTP/1.1" 200 3169 +lj1024.passgo.com - - [12/Mar/2004:02:27:29 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1123.passgo.com - - [12/Mar/2004:02:27:32 -0800] "GET /ops/SP/play//view/Sandbox/WebIndex HTTP/1.0" 200 8667 +195.11.231.210 - - [12/Mar/2004:03:32:56 -0800] "GET /mailman/listinfo/webber HTTP/1.0" 200 6032 +80.58.33.42.proxycache.rima-tde.net - - [12/Mar/2004:04:57:20 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +80.58.33.42.proxycache.rima-tde.net - - [12/Mar/2004:04:57:21 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +80.58.33.42.proxycache.rima-tde.net - - [12/Mar/2004:04:57:56 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.1" 200 4534 +200.100.10.5 - - [12/Mar/2004:04:59:21 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +200.100.10.5 - - [12/Mar/2004:04:59:21 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +lj1115.passgo.com - - [12/Mar/2004:05:03:19 -0800] "GET /ops/SP/play//view/Main/TWikiAdminGroup HTTP/1.0" 200 4156 +lj1008.passgo.com - - [12/Mar/2004:05:19:31 -0800] "GET /ops/SP/play//oops/TWiki/Mana HTTP/1.0" 200 209 +71.134.70.5 - - [12/Mar/2004:05:25:20 -0800] "GET /mailman/listinfo/cncce HTTP/1.1" 200 6208 +71.134.70.5 - - [12/Mar/2004:05:25:24 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +71.134.70.5 - - [12/Mar/2004:05:25:24 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +71.134.70.5 - - [12/Mar/2004:05:25:25 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +200.100.10.5 - - [12/Mar/2004:05:44:35 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +200.100.10.5 - - [12/Mar/2004:05:44:35 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +200.100.10.5 - - [12/Mar/2004:05:44:50 -0800] "GET /ops/SP/play//view/Main/DCC HTTP/1.1" 200 4396 +200.100.10.5 - - [12/Mar/2004:05:44:51 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +200.100.10.5 - - [12/Mar/2004:05:51:36 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +vlp181.vlp.fi - - [12/Mar/2004:08:33:32 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +lj1024.passgo.com - - [12/Mar/2004:09:12:01 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1223.passgo.com - - [12/Mar/2004:09:12:02 -0800] "GET /ops/SP/play//oops/Main/Mi HTTP/1.0" 200 209 +10.0.0.176 - - [12/Mar/2004:11:01:26 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [12/Mar/2004:11:01:28 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 6405 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6413 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6952 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8715 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 7001 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9514 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6644 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5554 +fassys.org - - [12/Mar/2004:11:16:36 -0800] "GET /ststats/ HTTP/1.0" 200 2955 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.0" 200 2925 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.0" 200 2347 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.0" 200 3431 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.0" 200 2380 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.0" 200 1658 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.0" 200 2685 +fassys.org - - [12/Mar/2004:11:16:56 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.0" 200 2082 +fassys.org - - [12/Mar/2004:11:16:56 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.0" 200 1637 +fassys.org - - [12/Mar/2004:11:16:56 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.0" 200 2211 +fassys.org - - [12/Mar/2004:11:16:56 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.0" 200 1853 +fassys.org - - [12/Mar/2004:11:16:56 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.0" 200 1572 +67.131.107.5 - - [12/Mar/2004:11:39:14 -0800] "GET / HTTP/1.1" 200 3169 +67.131.107.5 - - [12/Mar/2004:11:39:25 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +67.131.107.5 - - [12/Mar/2004:11:39:31 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +10.0.0.176 - - [12/Mar/2004:12:23:11 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [12/Mar/2004:12:23:17 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6324 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8964 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 6225 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 7001 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9514 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6949 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6644 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5554 +10.0.0.176 - - [12/Mar/2004:12:23:40 -0800] "GET /ststats/index.jsp HTTP/1.1" 304 - +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 2964 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2341 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2346 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3438 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1670 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2651 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 2023 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1636 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2262 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1906 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1582 +216.139.185.45 - - [12/Mar/2004:13:04:01 -0800] "GET /mailman/listinfo/webber HTTP/1.1" 200 6051 +pd95f99f2.dip.t-dialin.net - - [12/Mar/2004:13:18:57 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +d97082.upc-d.chello.nl - - [12/Mar/2004:13:25:45 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 diff --git a/rxjava/src/test/resources/expected_clob b/rxjava/src/test/resources/expected_clob new file mode 100644 index 0000000000..d7bc560556 --- /dev/null +++ b/rxjava/src/test/resources/expected_clob @@ -0,0 +1,1546 @@ +64.242.88.10 - - [07/Mar/2004:16:05:49 -0800] "GET /ops/SP/play//edit/Main/Double_bounce_sender?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:16:06:51 -0800] "GET /ops/SP/play//rdiff/TWiki/NewUserTemplate?rev1=1.3&rev2=1.2 HTTP/1.1" 200 4523 +64.242.88.10 - - [07/Mar/2004:16:10:02 -0800] "GET /mailman/listinfo/hsdivision HTTP/1.1" 200 6291 +64.242.88.10 - - [07/Mar/2004:16:11:58 -0800] "GET /ops/SP/play//view/TWiki/WikiSyntax HTTP/1.1" 200 7352 +64.242.88.10 - - [07/Mar/2004:16:20:55 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +64.242.88.10 - - [07/Mar/2004:16:23:12 -0800] "GET /ops/SP/play//oops/TWiki/AppendixFileSystem?template=oopsmore¶m1=1.12¶m2=1.12 HTTP/1.1" 200 11382 +64.242.88.10 - - [07/Mar/2004:16:24:16 -0800] "GET /ops/SP/play//view/Main/PeterThoeny HTTP/1.1" 200 4924 +64.242.88.10 - - [07/Mar/2004:16:29:16 -0800] "GET /ops/SP/play//edit/Main/Header_checks?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:16:30:29 -0800] "GET /ops/SP/play//attach/Main/OfficeLocations HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:16:31:48 -0800] "GET /ops/SP/play//view/TWiki/WebTopicEditTemplate HTTP/1.1" 200 3732 +64.242.88.10 - - [07/Mar/2004:16:32:50 -0800] "GET /ops/SP/play//view/Main/WebChanges HTTP/1.1" 200 40520 +64.242.88.10 - - [07/Mar/2004:16:33:53 -0800] "GET /ops/SP/play//edit/Main/Smtpd_etrn_restrictions?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:16:35:19 -0800] "GET /mailman/listinfo/business HTTP/1.1" 200 6379 +64.242.88.10 - - [07/Mar/2004:16:36:22 -0800] "GET /ops/SP/play//rdiff/Main/WebIndex?rev1=1.2&rev2=1.1 HTTP/1.1" 200 46373 +64.242.88.10 - - [07/Mar/2004:16:37:27 -0800] "GET /ops/SP/play//view/TWiki/DontNotify HTTP/1.1" 200 4140 +64.242.88.10 - - [07/Mar/2004:16:39:24 -0800] "GET /ops/SP/play//view/Main/TokyoOffice HTTP/1.1" 200 3853 +64.242.88.10 - - [07/Mar/2004:16:43:54 -0800] "GET /ops/SP/play//view/Main/MikeMannix HTTP/1.1" 200 3686 +64.242.88.10 - - [07/Mar/2004:16:45:56 -0800] "GET /ops/SP/play//attach/Main/PostfixCommands HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:16:47:12 -0800] "GET /robots.txt HTTP/1.1" 200 68 +64.242.88.10 - - [07/Mar/2004:16:47:46 -0800] "GET /ops/SP/play//rdiff/Know/ReadmeFirst?rev1=1.5&rev2=1.4 HTTP/1.1" 200 5724 +64.242.88.10 - - [07/Mar/2004:16:49:04 -0800] "GET /ops/SP/play//view/Main/TWikiGroups?rev=1.2 HTTP/1.1" 200 5162 +64.242.88.10 - - [07/Mar/2004:16:50:54 -0800] "GET /ops/SP/play//rdiff/Main/ConfigurationVariables HTTP/1.1" 200 59679 +64.242.88.10 - - [07/Mar/2004:16:52:35 -0800] "GET /ops/SP/play//edit/Main/Flush_service_name?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:16:53:46 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiRegistration HTTP/1.1" 200 34395 +64.242.88.10 - - [07/Mar/2004:16:54:55 -0800] "GET /ops/SP/play//rdiff/Main/NicholasLee HTTP/1.1" 200 7235 +64.242.88.10 - - [07/Mar/2004:16:56:39 -0800] "GET /ops/SP/play//view/Sandbox/WebHome?rev=1.6 HTTP/1.1" 200 8545 +64.242.88.10 - - [07/Mar/2004:16:58:54 -0800] "GET /mailman/listinfo/administration HTTP/1.1" 200 6459 +lordgun.org - - [07/Mar/2004:17:01:53 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +64.242.88.10 - - [07/Mar/2004:17:09:01 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Joris%20*Benschop[^A-Za-z] HTTP/1.1" 200 4284 +64.242.88.10 - - [07/Mar/2004:17:10:20 -0800] "GET /ops/SP/play//oops/TWiki/TextFormattingRules?template=oopsmore¶m1=1.37¶m2=1.37 HTTP/1.1" 200 11400 +64.242.88.10 - - [07/Mar/2004:17:13:50 -0800] "GET /ops/SP/play//edit/TWiki/DefaultPlugin?t=1078688936 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:17:16:00 -0800] "GET /ops/SP/play//search/Main/?scope=topic®ex=on&search=^g HTTP/1.1" 200 3675 +64.242.88.10 - - [07/Mar/2004:17:17:27 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^d HTTP/1.1" 200 5773 +lj1036.passgo.com - - [07/Mar/2004:17:18:36 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1090.passgo.com - - [07/Mar/2004:17:18:41 -0800] "GET /ops/SP/play//view/Main/LondonOffice HTTP/1.0" 200 3860 +64.242.88.10 - - [07/Mar/2004:17:21:44 -0800] "GET /ops/SP/play//attach/TWiki/TablePlugin HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:17:22:49 -0800] "GET /ops/SP/play//view/TWiki/ManagingWebs?rev=1.22 HTTP/1.1" 200 9310 +64.242.88.10 - - [07/Mar/2004:17:23:54 -0800] "GET /ops/SP/play//statistics/Main HTTP/1.1" 200 808 +64.242.88.10 - - [07/Mar/2004:17:26:30 -0800] "GET /ops/SP/play//view/TWiki/WikiCulture HTTP/1.1" 200 5935 +64.242.88.10 - - [07/Mar/2004:17:27:37 -0800] "GET /ops/SP/play//edit/Main/WebSearch?t=1078669682 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:17:28:45 -0800] "GET /ops/SP/play//oops/TWiki/ResetPassword?template=oopsmore¶m1=1.4¶m2=1.4 HTTP/1.1" 200 11281 +64.242.88.10 - - [07/Mar/2004:17:29:59 -0800] "GET /ops/SP/play//view/TWiki/ManagingWebs?skin=print HTTP/1.1" 200 8806 +64.242.88.10 - - [07/Mar/2004:17:31:39 -0800] "GET /ops/SP/play//edit/Main/UvscanAndPostFix?topicparent=Main.WebHome HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:17:35:35 -0800] "GET /ops/SP/play//view/TWiki/KlausWriessnegger HTTP/1.1" 200 3848 +64.242.88.10 - - [07/Mar/2004:17:39:39 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.1" 200 4081 +64.242.88.10 - - [07/Mar/2004:17:42:15 -0800] "GET /ops/SP/play//oops/TWiki/RichardDonkin?template=oopsmore¶m1=1.2¶m2=1.2 HTTP/1.1" 200 11281 +64.242.88.10 - - [07/Mar/2004:17:46:17 -0800] "GET /ops/SP/play//rdiff/TWiki/AlWilliams?rev1=1.3&rev2=1.2 HTTP/1.1" 200 4485 +64.242.88.10 - - [07/Mar/2004:17:47:43 -0800] "GET /ops/SP/play//rdiff/TWiki/AlWilliams?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5234 +64.242.88.10 - - [07/Mar/2004:17:50:44 -0800] "GET /ops/SP/play//view/TWiki/SvenDowideit HTTP/1.1" 200 3616 +64.242.88.10 - - [07/Mar/2004:17:53:45 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Office%20*Locations[^A-Za-z] HTTP/1.1" 200 7771 +64.242.88.10 - - [07/Mar/2004:17:56:54 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.31 HTTP/1.1" 200 23338 +64.242.88.10 - - [07/Mar/2004:17:58:00 -0800] "GET /ops/SP/play//edit/Main/KevinWGagel?t=1078670331 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:18:00:09 -0800] "GET /ops/SP/play//edit/Main/Virtual_mailbox_lock?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:18:02:10 -0800] "GET /ops/SP/play//view/Main/WebPreferences HTTP/1.1" 200 8820 +64.242.88.10 - - [07/Mar/2004:18:04:05 -0800] "GET /ops/SP/play//view/TWiki/WikiWord?rev=1.3 HTTP/1.1" 200 6816 +lj1125.passgo.com - - [07/Mar/2004:18:06:14 -0800] "GET /ops/SP/play//oops/Sandbox/WebChanges HTTP/1.0" 200 209 +64.242.88.10 - - [07/Mar/2004:18:09:00 -0800] "GET /ops/SP/play//rdiff/Main/TWikiGuest HTTP/1.1" 200 11314 +64.242.88.10 - - [07/Mar/2004:18:10:09 -0800] "GET /ops/SP/play//edit/TWiki/TWikiVariables?t=1078684115 HTTP/1.1" 401 12846 +d207-6-9-183.bchsia.telus.net - - [07/Mar/2004:18:10:18 -0800] "GET /pipermail/cncce/2004-January/000001.jsp HTTP/1.1" 200 3095 +d207-6-9-183.bchsia.telus.net - - [07/Mar/2004:18:10:20 -0800] "GET /pipermail/cncce/2004-January/000002.jsp HTTP/1.1" 200 3810 +64.242.88.10 - - [07/Mar/2004:18:17:26 -0800] "GET /ops/SP/play//rdiff/TWiki/WikiWord?rev1=1.4&rev2=1.3 HTTP/1.1" 200 6948 +64.242.88.10 - - [07/Mar/2004:18:19:01 -0800] "GET /ops/SP/play//edit/Main/TWikiPreferences?topicparent=Main.WebHome HTTP/1.1" 401 12846 +d207-6-9-183.bchsia.telus.net - - [07/Mar/2004:18:19:16 -0800] "GET /pipermail/cncce/2004-January.txt HTTP/1.1" 200 3376 +64.242.88.10 - - [07/Mar/2004:18:22:52 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Web%20*Statistics[^A-Za-z] HTTP/1.1" 200 3584 +64.242.88.10 - - [07/Mar/2004:18:26:32 -0800] "GET /ops/SP/play//rdiff/TWiki/PeterFokkinga?rev1=1.4&rev2=1.3 HTTP/1.1" 200 4548 +64.242.88.10 - - [07/Mar/2004:18:32:39 -0800] "GET /mailman/listinfo/dentalstudies HTTP/1.1" 200 6345 +64.242.88.10 - - [07/Mar/2004:18:34:42 -0800] "GET /ops/SP/play//view/Main/TWikiGuest HTTP/1.1" 200 4449 +64.242.88.10 - - [07/Mar/2004:18:42:29 -0800] "GET /ops/SP/play//attach/Main/TWikiGroups HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:18:46:00 -0800] "GET /ops/SP/play//rdiff/TWiki/TextFormattingRules?rev1=1.36&rev2=1.35 HTTP/1.1" 200 25416 +64.242.88.10 - - [07/Mar/2004:18:47:06 -0800] "GET /ops/SP/play//rdiff/Main/TWikiGroups?rev1=1.3&rev2=1.2 HTTP/1.1" 200 4308 +64.242.88.10 - - [07/Mar/2004:18:48:15 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=.* HTTP/1.1" 200 3544 +64.242.88.10 - - [07/Mar/2004:18:52:30 -0800] "GET /ops/SP/play//edit/Main/Trigger_timeout?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:18:53:55 -0800] "GET /ops/SP/play//oops/TWiki/TWikiSite?template=oopsmore¶m1=1.21¶m2=1.21 HTTP/1.1" 200 11284 +64.242.88.10 - - [07/Mar/2004:18:57:07 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.35 HTTP/1.1" 200 27248 +64.242.88.10 - - [07/Mar/2004:18:58:52 -0800] "GET /ops/SP/play//edit/Main/Mydestination?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:18:59:52 -0800] "GET /mailman/listinfo/fcd HTTP/1.1" 200 5967 +64.242.88.10 - - [07/Mar/2004:19:01:48 -0800] "GET /ops/SP/play//rdiff/Main/WebHome?rev1=1.28&rev2=1.27 HTTP/1.1" 200 3596 +64.242.88.10 - - [07/Mar/2004:19:03:58 -0800] "GET /ops/SP/play//edit/Main/Message_size_limit?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:19:08:55 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiHistory HTTP/1.1" 200 138789 +64.242.88.10 - - [07/Mar/2004:19:10:13 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^y HTTP/1.1" 200 3628 +64.242.88.10 - - [07/Mar/2004:19:15:38 -0800] "GET /ops/SP/play//edit/Main/Smtpd_history_flush_threshold?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:19:16:44 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=1.59 HTTP/1.1" 200 52854 +64.242.88.10 - - [07/Mar/2004:19:18:05 -0800] "GET /ops/SP/play//edit/Main/Sender_canonical_maps?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:19:19:19 -0800] "GET /mailman/listinfo/mlc HTTP/1.1" 200 6142 +64.242.88.10 - - [07/Mar/2004:19:21:01 -0800] "GET /ops/SP/play//rdiff/Main/WebChanges HTTP/1.1" 200 114241 +64.242.88.10 - - [07/Mar/2004:19:22:11 -0800] "GET /ops/SP/play//edit/Sandbox/TestTopic5?topicparent=Sandbox.WebHome HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:19:24:57 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.22 HTTP/1.1" 200 21162 +64.242.88.10 - - [07/Mar/2004:19:26:22 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^j HTTP/1.1" 200 4524 +64.242.88.10 - - [07/Mar/2004:19:29:46 -0800] "GET /ops/SP/play//oops/TWiki/TWikiVariables?template=oopsmore¶m1=1.62¶m2=1.62 HTTP/1.1" 200 11444 +64.242.88.10 - - [07/Mar/2004:19:31:25 -0800] "GET /ops/SP/play//edit/Main/Lmtp_connect_timeout?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:19:32:45 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^q HTTP/1.1" 200 2937 +64.242.88.10 - - [07/Mar/2004:19:36:14 -0800] "GET /ops/SP/play//view/TWiki/ManagingWebs?rev=1.21 HTTP/1.1" 200 9310 +64.242.88.10 - - [07/Mar/2004:19:39:40 -0800] "GET /ops/SP/play//edit/Main/Qmqpd_authorized_clients?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:19:41:33 -0800] "GET /ops/SP/play//edit/Main/Header_address_token_limit?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:19:42:45 -0800] "GET /ops/SP/play//edit/Main/Syslog_name?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +80-219-148-207.dclient.hispeed.ch - - [07/Mar/2004:19:47:36 -0800] "OPTIONS * HTTP/1.0" 200 - +64.242.88.10 - - [07/Mar/2004:19:49:28 -0800] "GET /ops/SP/play//oops/TWiki/TWikiHistory?template=oopsmore¶m1=1.61¶m2=1.61 HTTP/1.1" 200 11345 +64.242.88.10 - - [07/Mar/2004:19:52:28 -0800] "GET /ops/SP/play//view/TWiki/HaroldGottschalk HTTP/1.1" 200 3838 +64.242.88.10 - - [07/Mar/2004:19:54:33 -0800] "GET /ops/SP/play//view/TWiki/DefaultPlugin?rev=1.4 HTTP/1.1" 200 7298 +64.242.88.10 - - [07/Mar/2004:19:55:40 -0800] "GET /ops/SP/play//oops/TWiki/WelcomeGuest?template=oopsmore¶m1=1.20¶m2=1.20 HTTP/1.1" 200 11266 +64.242.88.10 - - [07/Mar/2004:19:56:41 -0800] "GET /ops/SP/play//rdiff/Main/WebIndex HTTP/1.1" 200 46373 +64.242.88.10 - - [07/Mar/2004:19:58:24 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiRegistration?rev1=1.10&rev2=1.9 HTTP/1.1" 200 3826 +64.242.88.10 - - [07/Mar/2004:20:00:06 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.21 HTTP/1.1" 200 20972 +64.242.88.10 - - [07/Mar/2004:20:02:13 -0800] "GET /ops/SP/play//attach/TWiki/DefaultPlugin HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:03:29 -0800] "GET /ops/SP/play//search/Main/?scope=topic®ex=on&search=^p HTTP/1.1" 200 7245 +206-15-133-181.dialup.ziplink.net - - [07/Mar/2004:20:04:03 -0800] "HEAD /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 0 +64.242.88.10 - - [07/Mar/2004:20:04:35 -0800] "GET /ops/SP/play//edit/Main/Smtp_pix_workaround_delay_time?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:07:12 -0800] "GET /ops/SP/play//edit/Main/Berkeley_db_create_buffer_size?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +mmscrm07-2.uah.goweb.net - - [07/Mar/2004:20:10:50 -0800] "GET /robots.txt HTTP/1.0" 200 68 +64.242.88.10 - - [07/Mar/2004:20:11:33 -0800] "GET /ops/SP/play//attach/TWiki/TWikiSite HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:12:55 -0800] "GET /ops/SP/play//edit/TWiki/TWikiSite?t=1078681794 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:23:35 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Web%20*Statistics[^A-Za-z] HTTP/1.1" 200 10118 +64.242.88.10 - - [07/Mar/2004:20:25:31 -0800] "GET /ops/SP/play//edit/Main/Defer_transports?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:31:40 -0800] "GET /ops/SP/play//rdiff/TWiki/SearchDoesNotWork HTTP/1.1" 200 6738 +64.242.88.10 - - [07/Mar/2004:20:35:28 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=TWiki%20*Admin%20*Group[^A-Za-z] HTTP/1.1" 200 7311 +64.242.88.10 - - [07/Mar/2004:20:38:14 -0800] "GET /ops/SP/play//rdiff/TWiki/ChangePassword HTTP/1.1" 200 16670 +64.242.88.10 - - [07/Mar/2004:20:40:41 -0800] "GET /ops/SP/play//rdiff/TWiki/SvenDowideit HTTP/1.1" 200 5277 +64.242.88.10 - - [07/Mar/2004:20:42:09 -0800] "GET /ops/SP/play//rdiff/TWiki/KevinKinnell?rev1=1.5&rev2=1.4 HTTP/1.1" 200 4982 +64.242.88.10 - - [07/Mar/2004:20:44:48 -0800] "GET /ops/SP/play//edit/Main/Undisclosed_recipients_header?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:20:55:43 -0800] "GET /mailman/listinfo/hs_support HTTP/1.1" 200 6294 +64.242.88.10 - - [07/Mar/2004:20:56:56 -0800] "GET /ops/SP/play//view/TWiki/WebTopicList HTTP/1.1" 200 14070 +64.242.88.10 - - [07/Mar/2004:20:58:27 -0800] "GET /ops/SP/play//attach/TWiki/WebPreferences HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:21:03:48 -0800] "GET /ops/SP/play//view/TWiki/TWikiFAQ HTTP/1.1" 200 12050 +64.242.88.10 - - [07/Mar/2004:21:06:05 -0800] "GET /ops/SP/play//oops/TWiki/DefaultPlugin?template=oopsmore¶m1=1.5¶m2=1.5 HTTP/1.1" 200 11281 +64.242.88.10 - - [07/Mar/2004:21:07:24 -0800] "GET /ops/SP/play//rdiff/TWiki/AppendixFileSystem?rev1=1.11&rev2=1.10 HTTP/1.1" 200 40578 +64.242.88.10 - - [07/Mar/2004:21:14:32 -0800] "GET /ops/SP/play//rdiff/TWiki/FileAttribute HTTP/1.1" 200 5846 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:17 -0800] "GET /twiki/view/Main/WebHome HTTP/1.1" 404 300 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:18 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:21 -0800] "GET /twiki/ HTTP/1.1" 200 782 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:23 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:23 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:33 -0800] "GET /ops/SP/play//view/Main/TWikiUsers HTTP/1.1" 200 6697 +h24-70-56-49.ca.clawio.org - - [07/Mar/2004:21:16:40 -0800] "GET /ops/SP/play//view/Main/KevinWGagel HTTP/1.1" 200 4901 +64.242.88.10 - - [07/Mar/2004:21:20:14 -0800] "GET /ops/SP/play//edit/TWiki/RichardDonkin?t=1078691832 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:21:21:40 -0800] "GET /ops/SP/play//oops/Main/DCC?template=oopsmore¶m1=1.1¶m2=1.1 HTTP/1.1" 200 6399 +64.242.88.10 - - [07/Mar/2004:21:23:38 -0800] "GET /ops/SP/play//view/TWiki/TWikiUpgradeTo01May2000 HTTP/1.1" 200 7463 +64.242.88.10 - - [07/Mar/2004:21:31:12 -0800] "GET /ops/SP/play//edit/Main/Mail_release_date?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:21:33:51 -0800] "GET /ops/SP/play//view/TWiki/TWikiPlugins?rev=1.19 HTTP/1.1" 200 26541 +bh02i525f01.au.ibm.com - - [07/Mar/2004:21:34:00 -0800] "GET /AmavisNew.jsp HTTP/1.0" 200 2300 +64.242.88.10 - - [07/Mar/2004:21:39:55 -0800] "GET /ops/SP/play//attach/Main/ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:21:41:04 -0800] "GET /mailman/listinfo/techcomm HTTP/1.1" 200 6155 +64.242.88.10 - - [07/Mar/2004:21:42:47 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=1.8 HTTP/1.1" 200 15618 +64.242.88.10 - - [07/Mar/2004:21:44:10 -0800] "GET /ops/SP/play//edit/Sandbox/TestTopic7?topicparent=Sandbox.WebHome HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:21:50:22 -0800] "GET /ops/SP/play//rdiff/TWiki/WebSearch HTTP/1.1" 200 55862 +64.242.88.10 - - [07/Mar/2004:21:52:05 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiTopics HTTP/1.1" 200 101445 +64.242.88.10 - - [07/Mar/2004:22:03:19 -0800] "GET /ops/SP/play//rdiff/Main/VishaalGolam HTTP/1.1" 200 5055 +64.242.88.10 - - [07/Mar/2004:22:04:44 -0800] "GET /ops/SP/play//view/Main/TWikiUsers?rev=1.21 HTTP/1.1" 200 6522 +64.242.88.10 - - [07/Mar/2004:22:06:16 -0800] "GET /ops/SP/play//edit/Main/Delay_notice_recipient?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:07:33 -0800] "GET /ops/SP/play//view/TWiki/WikiNotation HTTP/1.1" 200 3617 +64.242.88.10 - - [07/Mar/2004:22:08:43 -0800] "GET /ops/SP/play//edit/Main/Forward_expansion_filter?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:09:44 -0800] "GET /ops/SP/play//edit/Main/TestArea?topicparent=Main.WebHome HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:10:55 -0800] "GET /ops/SP/play//view/Main/TokyoOffice?rev=1.2 HTTP/1.1" 200 4366 +64.242.88.10 - - [07/Mar/2004:22:12:28 -0800] "GET /ops/SP/play//attach/TWiki/WebSearch HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:15:57 -0800] "GET /mailman/listinfo/hs_rcafaculty HTTP/1.1" 200 6345 +64.242.88.10 - - [07/Mar/2004:22:17:40 -0800] "GET /ops/SP/play//view/TWiki/TWikiSkins?skin=print HTTP/1.1" 200 9563 +64.242.88.10 - - [07/Mar/2004:22:27:18 -0800] "GET /ops/SP/play//edit/Main/OfficeLocations?t=1078691049 HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:29:10 -0800] "GET /ops/SP/play//view/Main/ThanadonSomdee HTTP/1.1" 200 4611 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:29:12 -0800] "GET /mailman/options/cnc_notice/arobin%40shaw.c HTTP/1.1" 200 3382 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:29:13 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:29:13 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:29:13 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:29:41 -0800] "POST /mailman/options/cnc_notice HTTP/1.1" 200 3533 +h24-71-249-14.ca.clawio.org - - [07/Mar/2004:22:30:08 -0800] "POST /mailman/options/cnc_notice HTTP/1.1" 200 13973 +64.242.88.10 - - [07/Mar/2004:22:31:25 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.16 HTTP/1.1" 200 17361 +64.242.88.10 - - [07/Mar/2004:22:35:53 -0800] "GET /ops/SP/play//edit/Main/Default_delivery_slot_discount?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:22:36:58 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiHistory?rev1=1.10&rev2=1.9 HTTP/1.1" 200 5336 +64.242.88.10 - - [07/Mar/2004:22:39:00 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Al%20*Williams[^A-Za-z] HTTP/1.1" 200 4364 +64.242.88.10 - - [07/Mar/2004:22:45:46 -0800] "GET /ops/SP/play//edit/Main/Smtpd_banner?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:22:47:19 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=r1.9 HTTP/1.1" 200 9133 +64.242.88.10 - - [07/Mar/2004:22:48:55 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiSkins?rev1=1.10&rev2=1.9 HTTP/1.1" 200 5989 +64.242.88.10 - - [07/Mar/2004:22:51:55 -0800] "GET /ops/SP/play//attach/TWiki/AndreaSterbini HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:22:53:36 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiPlugins?rev1=1.20&rev2=1.19 HTTP/1.1" 200 5140 +64.242.88.10 - - [07/Mar/2004:22:54:43 -0800] "GET /ops/SP/play//view/Know/ReadmeFirst?rev=1.4 HTTP/1.1" 200 6736 +64.242.88.10 - - [07/Mar/2004:22:58:24 -0800] "GET /ops/SP/play//view/Main/TokyoOffice?rev=r1.3 HTTP/1.1" 200 3853 +64.242.88.10 - - [07/Mar/2004:23:09:07 -0800] "GET /ops/SP/play//view/TWiki/AlWilliams?rev=1.1 HTTP/1.1" 200 3697 +calcite.rhyolite.com - - [07/Mar/2004:23:10:27 -0800] "GET /clients.jsp HTTP/1.1" 200 18753 +64.242.88.10 - - [07/Mar/2004:23:10:44 -0800] "GET /ops/SP/play//view/TWiki/JohnTalintyre HTTP/1.1" 200 3766 +64.242.88.10 - - [07/Mar/2004:23:13:51 -0800] "GET /ops/SP/play//view/TWiki/TWikiDocGraphics HTTP/1.1" 200 14492 +64.242.88.10 - - [07/Mar/2004:23:15:51 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.24 HTTP/1.1" 200 20981 +64.242.88.10 - - [07/Mar/2004:23:16:57 -0800] "GET /ops/SP/play//rdiff/Main/SanJoseOffice HTTP/1.1" 200 9524 +64.242.88.10 - - [07/Mar/2004:23:19:01 -0800] "GET /ops/SP/play//rdiff/Main/WebNotify HTTP/1.1" 200 16853 +64.242.88.10 - - [07/Mar/2004:23:20:26 -0800] "GET /ops/SP/play//view/TWiki/TWikiSiteTools HTTP/1.1" 200 14435 +64.242.88.10 - - [07/Mar/2004:23:23:00 -0800] "GET /ops/SP/play//rdiff/TWiki/RichardDonkin?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5891 +64.242.88.10 - - [07/Mar/2004:23:27:26 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Web%20*Preferences[^A-Za-z] HTTP/1.1" 200 20030 +64.242.88.10 - - [07/Mar/2004:23:30:23 -0800] "GET /ops/SP/play//rdiff/TWiki/WebHome HTTP/1.1" 200 108162 +64.242.88.10 - - [07/Mar/2004:23:34:31 -0800] "GET /ops/SP/play//edit/Main/Lmtp_quit_timeout?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [07/Mar/2004:23:36:48 -0800] "GET /ops/SP/play//view/TWiki/WebSiteTools HTTP/1.1" 200 5208 +lj1036.passgo.com - - [07/Mar/2004:23:36:59 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1088.passgo.com - - [07/Mar/2004:23:36:59 -0800] "GET /ops/SP/play//oops/TWiki/JohnAltstadt HTTP/1.0" 200 209 +64.242.88.10 - - [07/Mar/2004:23:37:48 -0800] "GET /ops/SP/play//oops/Main/FileAttachment?template=oopsmore¶m1=1.3¶m2=1.3 HTTP/1.1" 200 6612 +64.242.88.10 - - [07/Mar/2004:23:42:44 -0800] "GET /ops/SP/play//edit/Main/Cleanup_service_name?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [07/Mar/2004:23:47:58 -0800] "GET /ops/SP/play//view/TWiki/WikiReferences?skin=print HTTP/1.1" 200 5596 +64.242.88.10 - - [07/Mar/2004:23:50:03 -0800] "GET /ops/SP/play//view/Main/TokyoOffice?rev=1.3 HTTP/1.1" 200 3853 +64.242.88.10 - - [07/Mar/2004:23:51:38 -0800] "GET /ops/SP/play//view/Main/PostSuper?rev=r1.1 HTTP/1.1" 200 3629 +64.242.88.10 - - [07/Mar/2004:23:56:30 -0800] "GET /ops/SP/play//rdiff/Main/PostQueue HTTP/1.1" 200 4662 +64.242.88.10 - - [07/Mar/2004:23:58:53 -0800] "GET /ops/SP/play//edit/TWiki/TablePlugin?t=1078681446 HTTP/1.1" 401 12851 +dsl-80-43-113-44.access.uk.tiscali.com - - [08/Mar/2004:00:05:30 -0800] "GET / HTTP/1.1" 200 3169 +dsl-80-43-113-44.access.uk.tiscali.com - - [08/Mar/2004:00:05:35 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +dsl-80-43-113-44.access.uk.tiscali.com - - [08/Mar/2004:00:06:32 -0800] "GET /DCC.jsp HTTP/1.1" 200 2878 +64.242.88.10 - - [08/Mar/2004:00:08:58 -0800] "GET /ops/SP/play//oops/Sandbox/WebHome?template=oopsmore¶m1=1.7¶m2=1.7 HTTP/1.1" 200 4226 +64.242.88.10 - - [08/Mar/2004:00:11:22 -0800] "GET /ops/SP/play//edit/Main/WelcomeGuest?topicparent=Main.WebHome HTTP/1.1" 401 12846 +lj1125.passgo.com - - [08/Mar/2004:00:17:00 -0800] "GET /ops/SP/play//oops/Main/TWiki HTTP/1.0" 200 209 +64.242.88.10 - - [08/Mar/2004:00:17:22 -0800] "GET /ops/SP/play//view/TWiki/RichardDonkin?skin=print HTTP/1.1" 200 1729 +64.242.88.10 - - [08/Mar/2004:00:19:51 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=r1.4 HTTP/1.1" 200 7049 +64.242.88.10 - - [08/Mar/2004:00:21:54 -0800] "GET /ops/SP/play//view/TWiki/TWikiRegistration?rev=r1.7 HTTP/1.1" 200 12737 +64.242.88.10 - - [08/Mar/2004:00:25:11 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.26 HTTP/1.1" 200 22710 +64.242.88.10 - - [08/Mar/2004:00:27:53 -0800] "GET /ops/SP/play//view/TWiki/GoBox HTTP/1.1" 200 3762 +64.242.88.10 - - [08/Mar/2004:00:29:13 -0800] "GET /ops/SP/play//view/Main/FileAttachment?rev=1.1 HTTP/1.1" 200 17757 +64.242.88.10 - - [08/Mar/2004:00:32:45 -0800] "GET /ops/SP/play//attach/TWiki/KevinKinnell HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:00:36:21 -0800] "GET /ops/SP/play//rdiff/TWiki/WikiWikiClones HTTP/1.1" 200 9259 +64.242.88.10 - - [08/Mar/2004:00:37:23 -0800] "GET /ops/SP/play//oops/Main/NicholasLee?template=oopsmore¶m1=1.2¶m2=1.2 HTTP/1.1" 200 6558 +64.242.88.10 - - [08/Mar/2004:00:40:10 -0800] "GET /ops/SP/play//edit/Main/TWikiForms?topicparent=Main.TWikiVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:00:43:43 -0800] "GET /ops/SP/play//rdiff/TWiki/DefaultPlugin HTTP/1.1" 200 20376 +64.242.88.10 - - [08/Mar/2004:00:50:59 -0800] "GET /mailman/admin/educationadmin HTTP/1.1" 200 2150 +64.242.88.10 - - [08/Mar/2004:00:52:12 -0800] "GET /mailman/private/hsdivision/ HTTP/1.1" 200 1549 +64.242.88.10 - - [08/Mar/2004:00:54:26 -0800] "GET /mailman/listinfo/artsscience HTTP/1.1" 200 6248 +64.242.88.10 - - [08/Mar/2004:00:55:38 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^i HTTP/1.1" 200 7226 +64.242.88.10 - - [08/Mar/2004:01:00:08 -0800] "GET /ops/SP/play//rdiff/TWiki/AdrianLynch HTTP/1.1" 200 4011 +64.242.88.10 - - [08/Mar/2004:01:01:15 -0800] "GET /ops/SP/play//view/Main/WelcomeGuest HTTP/1.1" 200 4723 +64.242.88.10 - - [08/Mar/2004:01:02:16 -0800] "GET /ops/SP/play//view/Main/MikeMannix?rev=1.3 HTTP/1.1" 200 4721 +64.242.88.10 - - [08/Mar/2004:01:04:05 -0800] "GET /ops/SP/play//edit/TWiki/WikiStyleWord?topicparent=TWiki.TextFormattingFAQ HTTP/1.1" 401 12846 +lj1089.passgo.com - - [08/Mar/2004:01:04:54 -0800] "GET /ops/SP/play//oops/TWiki/InterWikis HTTP/1.0" 200 209 +64.242.88.10 - - [08/Mar/2004:01:10:43 -0800] "GET /ops/SP/play//view/TWiki/FormattedSearch?rev=1.8 HTTP/1.1" 200 20434 +64.242.88.10 - - [08/Mar/2004:01:12:20 -0800] "GET /ops/SP/play//view/TWiki/TWikiEnhancementRequests?rev=1.3 HTTP/1.1" 200 4379 +64.242.88.10 - - [08/Mar/2004:01:16:37 -0800] "GET /ops/SP/play//view/Main/FileAttachment?rev=1.2 HTTP/1.1" 200 17919 +64.242.88.10 - - [08/Mar/2004:01:19:18 -0800] "GET /ops/SP/play//edit/TWiki/AppendixFileSystem?t=1078674582 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:01:24:13 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.33 HTTP/1.1" 200 26294 +64.242.88.10 - - [08/Mar/2004:01:25:15 -0800] "GET /ops/SP/play//search/Main/?scope=topic®ex=on&search=^t HTTP/1.1" 200 8306 +64.242.88.10 - - [08/Mar/2004:01:29:17 -0800] "GET /ops/SP/play//oops/TWiki/TWikiPlugins?template=oopsmore¶m1=1.21¶m2=1.21 HTTP/1.1" 200 11341 +64.242.88.10 - - [08/Mar/2004:01:30:39 -0800] "GET /mailman/private/sswk/ HTTP/1.1" 200 1531 +64.242.88.10 - - [08/Mar/2004:01:33:14 -0800] "GET /mailman/private/business/ HTTP/1.1" 200 1543 +64.242.88.10 - - [08/Mar/2004:01:35:13 -0800] "GET /ops/SP/play//edit/TWiki/InterWikis?t=1078696998 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:01:41:14 -0800] "GET /ops/SP/play//view/TWiki/WelcomeGuest?rev=r1.18 HTTP/1.1" 200 14001 +64.242.88.10 - - [08/Mar/2004:01:46:05 -0800] "GET /ops/SP/play//search/TWiki/?search=\\.*&scope=topic&order=modified&reverse=on®ex=on&nosearch=on&limit=200 HTTP/1.1" 200 101279 +64.242.88.10 - - [08/Mar/2004:01:47:06 -0800] "GET /ops/SP/play//edit/TWiki/TWikiPages?topicparent=TWiki.WelcomeGuest HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:01:48:06 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=r1.16 HTTP/1.1" 200 9342 +64.242.88.10 - - [08/Mar/2004:01:50:37 -0800] "GET /ops/SP/play//rdiff/TWiki/RyanFreebern?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5243 +64.242.88.10 - - [08/Mar/2004:01:59:13 -0800] "GET /ops/SP/play//edit/Main/Smtp_line_length_limit?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:02:00:30 -0800] "GET /ops/SP/play//view/Main/WebStatistics?skin=print HTTP/1.1" 200 6194 +64.242.88.10 - - [08/Mar/2004:02:01:34 -0800] "GET /mailman/listinfo/webber HTTP/1.1" 200 6051 +64.242.88.10 - - [08/Mar/2004:02:03:12 -0800] "GET /mailman/admin/mlc HTTP/1.1" 200 2060 +64.242.88.10 - - [08/Mar/2004:02:05:15 -0800] "GET /mailman/listinfo/jjec HTTP/1.1" 200 6297 +64.242.88.10 - - [08/Mar/2004:02:06:17 -0800] "GET /mailman/listinfo/deans HTTP/1.1" 200 6102 +64.242.88.10 - - [08/Mar/2004:02:07:21 -0800] "GET /mailman/listinfo/gisgrad HTTP/1.1" 200 6024 +64.242.88.10 - - [08/Mar/2004:02:09:08 -0800] "GET /ops/SP/play//view/Main/WebNotify HTTP/1.1" 200 4468 +64.242.88.10 - - [08/Mar/2004:02:12:24 -0800] "GET /ops/SP/play//edit/Main/Setgid_group?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:02:16:24 -0800] "GET /ops/SP/play//view/Main/WebChanges?skin=print HTTP/1.1" 200 38580 +lj1016.passgo.com - - [08/Mar/2004:02:17:10 -0800] "GET /ops/SP/play//oops/TWiki/FileAttachment HTTP/1.0" 200 209 +lj1036.passgo.com - - [08/Mar/2004:02:22:19 -0800] "GET /ops/SP/play//view/Main/TWi HTTP/1.0" 200 4866 +64.242.88.10 - - [08/Mar/2004:02:23:45 -0800] "GET /ops/SP/play//rdiff/TWiki/IncludeTopicsAndWebPages HTTP/1.1" 200 20972 +64.242.88.10 - - [08/Mar/2004:02:26:44 -0800] "GET /ops/SP/play//oops/Main/WebChanges?template=oopsmore¶m1=1.2¶m2=1.2 HTTP/1.1" 200 6540 +64.242.88.10 - - [08/Mar/2004:02:27:51 -0800] "GET /ops/SP/play//rdiff/TWiki/InstantEnhancements HTTP/1.1" 200 25123 +64.242.88.10 - - [08/Mar/2004:02:33:28 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiPreferences?rev1=1.47&rev2=1.46 HTTP/1.1" 200 4313 +64.242.88.10 - - [08/Mar/2004:02:34:40 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=r1.24 HTTP/1.1" 200 9769 +64.242.88.10 - - [08/Mar/2004:02:42:36 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +64.242.88.10 - - [08/Mar/2004:02:45:03 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&bookview=on&search=.* HTTP/1.1" 200 102399 +64.242.88.10 - - [08/Mar/2004:02:46:12 -0800] "GET /ops/SP/play//edit/Main/Local_recipient_maps?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:02:47:58 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +lj1025.passgo.com - - [08/Mar/2004:02:48:05 -0800] "GET /ops/SP/play//oops/Main/KevinWGage HTTP/1.0" 200 209 +prxint-sxb3.e-i.net - - [08/Mar/2004:02:50:53 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +prxint-sxb3.e-i.net - - [08/Mar/2004:02:50:54 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +64.242.88.10 - - [08/Mar/2004:02:52:39 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.1" 200 4173 +prxint-sxb2.e-i.net - - [08/Mar/2004:02:54:29 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.0" 200 4022 +64.242.88.10 - - [08/Mar/2004:02:54:54 -0800] "GET /ops/SP/play//edit/TWiki/NewTopic?topicparent=TWiki.WikiSyntax HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:02:59:03 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiSite HTTP/1.1" 200 71941 +64.242.88.10 - - [08/Mar/2004:03:01:12 -0800] "GET /ops/SP/play//rdiff/TWiki/SimultaneousEdits HTTP/1.1" 200 6180 +64.242.88.10 - - [08/Mar/2004:03:06:31 -0800] "GET /ops/SP/play//view/Main/NicholasLee?rev=1.2 HTTP/1.1" 200 3570 +64.242.88.10 - - [08/Mar/2004:03:07:59 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=1.9 HTTP/1.1" 200 15756 +64.242.88.10 - - [08/Mar/2004:03:09:20 -0800] "GET /mailman/listinfo/ncbnpfaculty HTTP/1.1" 200 6331 +64.242.88.10 - - [08/Mar/2004:03:11:28 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Inter%20*Wikis[^A-Za-z] HTTP/1.1" 200 5113 +64.242.88.10 - - [08/Mar/2004:03:16:22 -0800] "GET /ops/SP/play//oops/TWiki/TextFormattingFAQ?template=oopsmore¶m1=1.14¶m2=1.14 HTTP/1.1" 200 11364 +64.242.88.10 - - [08/Mar/2004:03:17:50 -0800] "GET /ops/SP/play//rdiff/Main/WebTopicList HTTP/1.1" 200 8004 +64.242.88.10 - - [08/Mar/2004:03:21:16 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +64.242.88.10 - - [08/Mar/2004:03:26:06 -0800] "GET /mailman/private/mlc/ HTTP/1.1" 200 1528 +64.242.88.10 - - [08/Mar/2004:03:28:02 -0800] "GET /ops/SP/play//view/TWiki/WikiName HTTP/1.1" 200 4811 +64.242.88.10 - - [08/Mar/2004:03:33:52 -0800] "GET /ops/SP/play//rdiff/Main/WebRss HTTP/1.1" 200 20726 +64.242.88.10 - - [08/Mar/2004:03:35:42 -0800] "GET /ops/SP/play//rdiff/TWiki/SvenDowideit?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5277 +rouble.cc.strath.ac.uk - - [08/Mar/2004:03:40:51 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +213.181.81.4 - - [08/Mar/2004:03:42:20 -0800] "GET /LateEmail.jsp HTTP/1.0" 200 7649 +64.242.88.10 - - [08/Mar/2004:03:46:27 -0800] "GET /ops/SP/play//edit/Main/Deliver_lock_attempts?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:03:48:18 -0800] "GET /ops/SP/play//edit/Main/Daemon_directory?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:03:49:24 -0800] "GET /ops/SP/play//rdiff/TWiki/KlausWriessnegger?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5421 +64.242.88.10 - - [08/Mar/2004:03:51:05 -0800] "GET /ops/SP/play//view/Main/TWikiGuest?rev=1.4 HTTP/1.1" 200 4719 +64.242.88.10 - - [08/Mar/2004:03:52:17 -0800] "GET /ops/SP/play//edit/Main/Relayhost?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +lj1036.passgo.com - - [08/Mar/2004:03:53:59 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1159.passgo.com - - [08/Mar/2004:03:54:03 -0800] "GET /ops/SP/play//oops/Main/TWi HTTP/1.0" 200 209 +64.242.88.10 - - [08/Mar/2004:03:55:09 -0800] "GET /ops/SP/play//edit/Main/BookView?topicparent=Main.TWikiVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:04:16:08 -0800] "GET /ops/SP/play//rdiff/TWiki/DeleteOrRenameATopic HTTP/1.1" 200 10254 +64.242.88.10 - - [08/Mar/2004:04:18:28 -0800] "GET /ops/SP/play//view/TWiki/DavidWarman HTTP/1.1" 200 3739 +64.242.88.10 - - [08/Mar/2004:04:20:48 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.28 HTTP/1.1" 200 22777 +64.242.88.10 - - [08/Mar/2004:04:21:53 -0800] "GET /ops/SP/play//rdiff/Main/PeterThoeny HTTP/1.1" 200 18927 +64.242.88.10 - - [08/Mar/2004:04:22:55 -0800] "GET /ops/SP/play//edit/TWiki/SvenDowideit?t=1078710644 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:04:24:47 -0800] "GET /ops/SP/play//edit/Main/RBLsHowTo?t=1078668449 HTTP/1.1" 401 12846 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:25:38 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.0" 200 5672 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:25:44 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:26:02 -0800] "GET /ops/SP/play//view/Main/SideBar HTTP/1.0" 200 3960 +64.242.88.10 - - [08/Mar/2004:04:26:02 -0800] "GET /ops/SP/play//rdiff/TWiki/DefaultPlugin?rev1=1.5&rev2=1.4 HTTP/1.1" 200 4911 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:26:11 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.0" 200 4515 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:28:34 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.0" 200 4213 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:28:38 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.0" 200 4004 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:28:41 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.0" 200 4154 +64.242.88.10 - - [08/Mar/2004:04:28:42 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiHistory?rev1=1.61&rev2=1.60 HTTP/1.1" 200 4898 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:28:52 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.0" 200 3617 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:29:00 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.0" 200 4646 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:29:11 -0800] "GET /ops/SP/play//view/Main/ConfigurationVariables HTTP/1.0" 200 58169 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:29:21 -0800] "GET /ops/SP/play//edit/Main/Propagate_unmatched_extensions?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +prxint-sxb3.e-i.net - - [08/Mar/2004:04:29:30 -0800] "GET /go/bin/test/TWikiDocGraphics/help.gif HTTP/1.0" 200 130 +64.242.88.10 - - [08/Mar/2004:04:33:25 -0800] "GET /mailman/admin/hs_support HTTP/1.1" 200 2120 +64.242.88.10 - - [08/Mar/2004:04:40:32 -0800] "GET /ops/SP/play//edit/Main/Always_bcc?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:04:43:52 -0800] "GET /ops/SP/play//view/TWiki/WelcomeGuest?rev=r1.5 HTTP/1.1" 200 9492 +64.242.88.10 - - [08/Mar/2004:04:52:13 -0800] "GET /ops/SP/play//rdiff/Main/TWikiGuest?rev1=1.5&rev2=1.4 HTTP/1.1" 200 6233 +64.242.88.10 - - [08/Mar/2004:04:55:40 -0800] "GET /ops/SP/play//edit/Main/Delay_warning_time?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:04:59:13 -0800] "GET /ops/SP/play//edit/TWiki/KlausWriessnegger?t=1078709735 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:05:00:42 -0800] "GET /ops/SP/play//rdiff/TWiki/StanleyKnutson HTTP/1.1" 200 5327 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:00:44 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:00:45 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:00:46 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:00:52 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:01:02 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:01:14 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +64.242.88.10 - - [08/Mar/2004:05:01:58 -0800] "GET /ops/SP/play//view/TWiki/WhatIsWikiWiki HTTP/1.1" 200 4234 +200.160.249.68.bmf.com.br - - [08/Mar/2004:05:02:06 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +200.160.249.68.bmf.com.br - - [08/Mar/2004:05:02:07 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +64.242.88.10 - - [08/Mar/2004:05:03:13 -0800] "GET /ops/SP/play//view/Main/WebIndex?rev=1.1 HTTP/1.1" 200 44960 +64.242.88.10 - - [08/Mar/2004:05:13:35 -0800] "GET /mailman/private/hs_support/ HTTP/1.1" 200 1549 +68-174-110-154.nyc.rr.com - - [08/Mar/2004:05:16:15 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +68-174-110-154.nyc.rr.com - - [08/Mar/2004:05:16:20 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +64.242.88.10 - - [08/Mar/2004:05:22:57 -0800] "GET /ops/SP/play//attach/Sandbox/WebHome HTTP/1.1" 401 12846 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:23:37 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +66-194-6-70.gen.twtelecom.net - - [08/Mar/2004:05:24:18 -0800] "GET / HTTP/1.1" 200 3169 +64.242.88.10 - - [08/Mar/2004:05:24:29 -0800] "GET /ops/SP/play//edit/TWiki/UnchangeableTopicBug?topicparent=TWiki.TWikiHistory HTTP/1.1" 401 12846 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:24:50 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:25:46 -0800] "GET /ops/SP/play//view/Main/Postfix HTTP/1.1" 200 3699 +64.242.88.10 - - [08/Mar/2004:05:26:02 -0800] "GET /ops/SP/play//view/Main/TWikiGuest?skin=print HTTP/1.1" 200 2372 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:26:06 -0800] "GET /ops/SP/play//edit/Main/UvscanAndPostFix?topicparent=Main.WebHome HTTP/1.1" 401 12851 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:26:08 -0800] "GET /go/bin/test/TWikiDocGraphics/help.gif HTTP/1.1" 200 130 +p213.54.168.132.tisdip.tiscali.de - - [08/Mar/2004:05:26:16 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +64.242.88.10 - - [08/Mar/2004:05:30:07 -0800] "GET /ops/SP/play//view/TWiki/SvenDowideit?rev=1.1 HTTP/1.1" 200 3564 +64.242.88.10 - - [08/Mar/2004:05:31:47 -0800] "GET /ops/SP/play//edit/Main/Maps_rbl_reject_code?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +lj1027.passgo.com - - [08/Mar/2004:05:32:01 -0800] "GET /ops/SP/play//view/TWiki/2fa HTTP/1.0" 200 4615 +64.242.88.10 - - [08/Mar/2004:05:34:33 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Web%20*Changes[^A-Za-z] HTTP/1.1" 200 4829 +64.242.88.10 - - [08/Mar/2004:05:36:56 -0800] "GET /ops/SP/play//edit/Main/WebStatistics?t=1078690975 HTTP/1.1" 401 12851 +68-174-110-154.nyc.rr.com - - [08/Mar/2004:05:38:57 -0800] "GET /razor.jsp HTTP/1.1" 304 - +64.242.88.10 - - [08/Mar/2004:05:42:06 -0800] "GET /ops/SP/play//view/Main/RelayGateway?rev=1.3 HTTP/1.1" 200 4232 +64.242.88.10 - - [08/Mar/2004:05:47:38 -0800] "GET /robots.txt HTTP/1.1" 200 68 +64.242.88.10 - - [08/Mar/2004:05:48:48 -0800] "GET /ops/SP/play//rdiff/TWiki/KevinKinnell?rev1=1.4&rev2=1.3 HTTP/1.1" 200 4369 +64.242.88.10 - - [08/Mar/2004:05:51:45 -0800] "GET /ops/SP/play//view/TWiki/WelcomeGuest?rev=r1.11 HTTP/1.1" 200 13102 +64.242.88.10 - - [08/Mar/2004:05:56:08 -0800] "GET /ops/SP/play//view/TWiki/TWikiRegistration?rev=r1.4 HTTP/1.1" 200 12113 +64.242.88.10 - - [08/Mar/2004:05:57:15 -0800] "GET /ops/SP/play//edit/TWiki/TWikiCodevTWikiEnhancementRequests?topicparent=TWiki.TWikiHistory HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:05:58:39 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Peter%20*Fokkinga[^A-Za-z] HTTP/1.1" 200 4388 +64.242.88.10 - - [08/Mar/2004:06:01:51 -0800] "GET /ops/SP/play//attach/Main/WebPreferences HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:06:09:37 -0800] "GET /mailman/admin/hs_rcafaculty HTTP/1.1" 200 2144 +64.242.88.10 - - [08/Mar/2004:06:17:13 -0800] "GET /ops/SP/play//rdiff/TWiki/WebChanges HTTP/1.1" 200 114167 +64.242.88.10 - - [08/Mar/2004:06:20:36 -0800] "GET /ops/SP/play//view/Main/JorisBenschop?skin=print HTTP/1.1" 200 2717 +64.242.88.10 - - [08/Mar/2004:06:23:52 -0800] "GET /ops/SP/play//edit/TWiki/TestArea?topicparent=TWiki.WelcomeGuest HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:06:32:14 -0800] "GET /ops/SP/play//view/TWiki/WelcomeGuest?rev=r1.6 HTTP/1.1" 200 12620 +64.242.88.10 - - [08/Mar/2004:06:37:19 -0800] "GET /ops/SP/play//rdiff/TWiki/HaroldGottschalk?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5389 +64.242.88.10 - - [08/Mar/2004:06:41:22 -0800] "GET /pipermail/techcomm/ HTTP/1.1" 200 1176 +64.242.88.10 - - [08/Mar/2004:06:42:29 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.19 HTTP/1.1" 200 20488 +64.242.88.10 - - [08/Mar/2004:06:43:32 -0800] "GET /ops/SP/play//edit/Sandbox/TestTopic2?topicparent=Sandbox.WebHome HTTP/1.1" 401 12846 +128.227.88.79 - - [08/Mar/2004:06:47:41 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +128.227.88.79 - - [08/Mar/2004:06:47:41 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +64.242.88.10 - - [08/Mar/2004:06:49:27 -0800] "GET /ops/SP/play//attach/TWiki/InterWikis HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:06:54:30 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiSkins?rev1=1.11&rev2=1.10 HTTP/1.1" 200 5711 +64.242.88.10 - - [08/Mar/2004:06:57:09 -0800] "GET /ops/SP/play//rdiff/TWiki/WebNotify HTTP/1.1" 200 11780 +128.227.88.79 - - [08/Mar/2004:06:57:46 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +128.227.88.79 - - [08/Mar/2004:06:57:46 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +64.242.88.10 - - [08/Mar/2004:07:00:15 -0800] "GET /ops/SP/play//view/TWiki/DontNotify?rev=1.1 HTTP/1.1" 200 3965 +64.242.88.10 - - [08/Mar/2004:07:07:13 -0800] "GET /ops/SP/play//edit/Main/Masquerade_classes?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +128.227.88.79 - - [08/Mar/2004:07:09:12 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.1" 200 4081 +64.242.88.10 - - [08/Mar/2004:07:09:21 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=r1.10 HTTP/1.1" 200 8312 +64.242.88.10 - - [08/Mar/2004:07:10:26 -0800] "GET /ops/SP/play//view/TWiki/HaroldGottschalk?rev=1.2 HTTP/1.1" 200 3774 +64.242.88.10 - - [08/Mar/2004:07:11:37 -0800] "GET /ops/SP/play//edit/TWiki/TWikiCodevTWikiPlannedFeatures?topicparent=TWiki.TWikiHistory HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:07:12:39 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=r1.44 HTTP/1.1" 200 41434 +64.242.88.10 - - [08/Mar/2004:07:22:13 -0800] "GET /ops/SP/play//view/TWiki/PeterFokkinga?rev=1.2 HTTP/1.1" 200 3748 +64.242.88.10 - - [08/Mar/2004:07:23:38 -0800] "GET /ops/SP/play//edit/TWiki/TWikiPlugins?t=1078696313 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:07:24:43 -0800] "GET /mailman/listinfo/webct HTTP/1.1" 200 6377 +64.242.88.10 - - [08/Mar/2004:07:25:56 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +64.242.88.10 - - [08/Mar/2004:07:27:01 -0800] "GET /mailman/listinfo/faculty HTTP/1.1" 200 6054 +61.9.4.61 - - [08/Mar/2004:07:27:36 -0800] "GET /_vti_bin/owssvr.dll?UL=1&ACT=4&BUILD=2614&STRMVER=4&CAPREQ=0 HTTP/1.0" 404 284 +61.9.4.61 - - [08/Mar/2004:07:27:36 -0800] "GET /SpamAssassin.jsp HTTP/1.0" 200 7368 +61.9.4.61 - - [08/Mar/2004:07:27:37 -0800] "GET /MSOffice/cltreq.asp?UL=1&ACT=4&BUILD=2614&STRMVER=4&CAPREQ=0 HTTP/1.0" 404 284 +64.242.88.10 - - [08/Mar/2004:07:28:29 -0800] "GET /mailman/admin/sswk HTTP/1.1" 200 2072 +64.242.88.10 - - [08/Mar/2004:07:29:56 -0800] "GET /mailman/listinfo/purchasing HTTP/1.1" 200 6050 +64.242.88.10 - - [08/Mar/2004:07:35:50 -0800] "GET /ops/SP/play//edit/Main/Invalid_hostname_reject_code?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:07:39:31 -0800] "GET /ops/SP/play//rdiff/Main/WebPreferences?rev1=1.14&rev2=1.13 HTTP/1.1" 200 7207 +64.242.88.10 - - [08/Mar/2004:07:40:54 -0800] "GET /ops/SP/play//rename/TWiki/TWikiHistory HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:07:43:21 -0800] "GET /ops/SP/play//view/TWiki/SearchDoesNotWork?rev=r1.2 HTTP/1.1" 200 4072 +64.242.88.10 - - [08/Mar/2004:07:44:53 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=r1.50 HTTP/1.1" 200 42285 +64.242.88.10 - - [08/Mar/2004:07:49:56 -0800] "GET /ops/SP/play//edit/TWiki/RyanFreebern?t=1078701457 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:07:51:39 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=r1.2 HTTP/1.1" 200 6061 +64.242.88.10 - - [08/Mar/2004:07:53:19 -0800] "GET /ops/SP/play//rdiff/TWiki/WebTopicEditTemplate HTTP/1.1" 200 7895 +mcl02.tnr.on.ca - - [08/Mar/2004:07:53:37 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +mcl02.tnr.on.ca - - [08/Mar/2004:07:53:38 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +mcl02.tnr.on.ca - - [08/Mar/2004:07:53:38 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +mcl02.tnr.on.ca - - [08/Mar/2004:07:53:38 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +64.242.88.10 - - [08/Mar/2004:07:54:30 -0800] "GET /ops/SP/play//edit/Main/Unknown_local_recipient_reject_code?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:07:56:34 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Web%20*Index[^A-Za-z] HTTP/1.1" 200 4163 +64.242.88.10 - - [08/Mar/2004:08:04:46 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +p5083cd5d.dip0.t-ipconnect.de - - [08/Mar/2004:08:09:32 -0800] "GET /SpamAssassin.jsp HTTP/1.0" 200 7368 +64.242.88.10 - - [08/Mar/2004:08:12:50 -0800] "GET /ops/SP/play//view/TWiki/ChangePassword?rev=r1.6 HTTP/1.1" 200 5181 +64.242.88.10 - - [08/Mar/2004:08:14:15 -0800] "GET /ops/SP/play//edit/TWiki/HaroldGottschalk?t=1078717948 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:08:15:21 -0800] "GET /ops/SP/play//edit/Main/Expand_owner_alias?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:08:17:09 -0800] "GET /ops/SP/play//view/Main/WebIndex?rev=r1.2 HTTP/1.1" 200 45059 +64.242.88.10 - - [08/Mar/2004:08:18:52 -0800] "GET /rfc.jsp HTTP/1.1" 200 3103 +pool-68-160-195-60.ny325.east.verizon.net - - [08/Mar/2004:08:21:00 -0800] "GET / HTTP/1.1" 200 3169 +pool-68-160-195-60.ny325.east.verizon.net - - [08/Mar/2004:08:21:00 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +64.242.88.10 - - [08/Mar/2004:08:21:47 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=RBLs%20*How%20*To[^A-Za-z] HTTP/1.1" 200 3575 +64.242.88.10 - - [08/Mar/2004:08:25:37 -0800] "GET /ops/SP/play//rdiff/TWiki/WebTopicEditTemplate?rev1=1.5&rev2=1.4 HTTP/1.1" 200 4212 +212.92.37.62 - - [08/Mar/2004:08:26:41 -0800] "GET / HTTP/1.1" 200 3169 +212.92.37.62 - - [08/Mar/2004:08:27:04 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +212.92.37.62 - - [08/Mar/2004:08:27:08 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +64.242.88.10 - - [08/Mar/2004:08:27:14 -0800] "GET /ops/SP/play//rdiff/Main/SpamAssassin HTTP/1.1" 200 4445 +212.92.37.62 - - [08/Mar/2004:08:27:23 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +212.92.37.62 - - [08/Mar/2004:08:27:28 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +64.242.88.10 - - [08/Mar/2004:08:28:23 -0800] "GET /ops/SP/play//rdiff/Main/TokyoOffice?rev1=1.2&rev2=1.1 HTTP/1.1" 200 7316 +64.242.88.10 - - [08/Mar/2004:08:29:36 -0800] "GET /ops/SP/play//view/TWiki/TWikiCategoryTable HTTP/1.1" 200 3729 +219.95.17.51 - - [08/Mar/2004:08:29:57 -0800] "GET / HTTP/1.1" 200 3169 +212.92.37.62 - - [08/Mar/2004:08:30:25 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +212.92.37.62 - - [08/Mar/2004:08:31:37 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +10.0.0.176 - - [08/Mar/2004:08:32:24 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:08:32:27 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +10.0.0.176 - - [08/Mar/2004:08:32:27 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +212.92.37.62 - - [08/Mar/2004:08:32:34 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +212.92.37.62 - - [08/Mar/2004:08:33:27 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +212.92.37.62 - - [08/Mar/2004:08:33:30 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.1" 200 4173 +212.92.37.62 - - [08/Mar/2004:08:33:39 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.1" 200 3629 +64.242.88.10 - - [08/Mar/2004:08:33:51 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=r1.14 HTTP/1.1" 200 8820 +212.92.37.62 - - [08/Mar/2004:08:33:52 -0800] "GET /ops/SP/play//view/Main/SideBar HTTP/1.1" 200 3972 +212.92.37.62 - - [08/Mar/2004:08:33:57 -0800] "GET /ops/SP/play//view/Main/DCCGraphs HTTP/1.1" 200 5402 +212.92.37.62 - - [08/Mar/2004:08:34:09 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +64.242.88.10 - - [08/Mar/2004:08:34:53 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiHistory?rev1=1.8&rev2=1.7 HTTP/1.1" 200 4972 +64.242.88.10 - - [08/Mar/2004:08:36:05 -0800] "GET /ops/SP/play//view/TWiki/ChangePassword?rev=r1.3 HTTP/1.1" 200 5229 +92-moc-6.acn.waw.pl - - [08/Mar/2004:08:37:14 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +92-moc-6.acn.waw.pl - - [08/Mar/2004:08:37:14 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +92-moc-6.acn.waw.pl - - [08/Mar/2004:08:37:17 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +64.242.88.10 - - [08/Mar/2004:08:37:23 -0800] "GET /ops/SP/play//attach/TWiki/HaroldGottschalk HTTP/1.1" 401 12846 +66.213.206.2 - - [08/Mar/2004:08:37:53 -0800] "GET / HTTP/1.1" 200 3169 +64.242.88.10 - - [08/Mar/2004:08:40:15 -0800] "GET /LateEmail.jsp HTTP/1.1" 200 7649 +64.242.88.10 - - [08/Mar/2004:08:52:13 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.15 HTTP/1.1" 200 16746 +64.242.88.10 - - [08/Mar/2004:08:53:17 -0800] "GET /ops/SP/play//view/TWiki/TWikiTutorial HTTP/1.1" 200 14485 +64.242.88.10 - - [08/Mar/2004:08:55:12 -0800] "GET /mailman/private/dentalstudies/ HTTP/1.1" 200 1558 +spot.nnacorp.com - - [08/Mar/2004:09:02:14 -0800] "GET / HTTP/1.1" 200 3169 +spot.nnacorp.com - - [08/Mar/2004:09:02:21 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +spot.nnacorp.com - - [08/Mar/2004:09:02:21 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +10.0.0.176 - - [08/Mar/2004:09:02:29 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:09:02:31 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 7326 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 7927 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7182 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8866 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9307 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6805 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6596 +10.0.0.176 - - [08/Mar/2004:09:02:32 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5499 +spot.nnacorp.com - - [08/Mar/2004:09:02:54 -0800] "GET /ops/SP/play//view/Main/TWikiUsers HTTP/1.1" 200 6697 +spot.nnacorp.com - - [08/Mar/2004:09:02:54 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +64.242.88.10 - - [08/Mar/2004:09:03:18 -0800] "GET /ststats/index.jsp HTTP/1.1" 200 2955 +64.242.88.10 - - [08/Mar/2004:09:05:54 -0800] "GET /ops/SP/play//edit/Sandbox/TestTopic6?topicparent=Sandbox.WebHome HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:09:09:55 -0800] "GET /ops/SP/play//view/TWiki/TablePlugin?skin=print HTTP/1.1" 200 1572 +64.242.88.10 - - [08/Mar/2004:09:12:54 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Spam%20*Assassin[^A-Za-z] HTTP/1.1" 200 8782 +lhr003a.dhl.com - - [08/Mar/2004:09:16:26 -0800] "GET / HTTP/1.0" 200 3169 +lhr003a.dhl.com - - [08/Mar/2004:09:17:16 -0800] "GET /ststats/index.jsp HTTP/1.0" 200 2955 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.0" 200 3040 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.0" 200 2341 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.0" 200 2271 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.0" 200 3302 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.0" 200 1663 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.0" 200 2521 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.0" 200 1918 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.0" 200 1580 +lhr003a.dhl.com - - [08/Mar/2004:09:17:17 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.0" 200 2202 +lhr003a.dhl.com - - [08/Mar/2004:09:17:18 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.0" 200 1822 +lhr003a.dhl.com - - [08/Mar/2004:09:17:18 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.0" 200 1526 +10.0.0.176 - - [08/Mar/2004:09:18:53 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:09:18:56 -0800] "GET /ststats/index.jsp HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3040 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2271 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2341 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3302 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1580 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1918 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1663 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2202 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2521 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1822 +10.0.0.176 - - [08/Mar/2004:09:18:57 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1526 +64.242.88.10 - - [08/Mar/2004:09:23:03 -0800] "GET /ops/SP/play//view/TWiki/SearchDoesNotWork?rev=r1.1 HTTP/1.1" 200 3981 +64.242.88.10 - - [08/Mar/2004:09:25:42 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=TWiki%20*FAQ[^A-Za-z] HTTP/1.1" 200 12083 +lj1036.passgo.com - - [08/Mar/2004:09:29:35 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1027.passgo.com - - [08/Mar/2004:09:29:36 -0800] "GET /ops/SP/play//oops/Know/WinDoze95Crash HTTP/1.0" 200 209 +pool-68-160-195-60.ny325.east.verizon.net - - [08/Mar/2004:09:30:10 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +pool-68-160-195-60.ny325.east.verizon.net - - [08/Mar/2004:09:30:11 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +pool-68-160-195-60.ny325.east.verizon.net - - [08/Mar/2004:09:30:11 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +64.242.88.10 - - [08/Mar/2004:09:30:40 -0800] "GET /ops/SP/play//view/TWiki/WebSearch?rev=r1.10 HTTP/1.1" 200 9419 +64.242.88.10 - - [08/Mar/2004:09:32:32 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiDownload HTTP/1.1" 200 5933 +64.242.88.10 - - [08/Mar/2004:09:33:46 -0800] "GET /ops/SP/play//view/Main/SideBar?rev=1.1 HTTP/1.1" 200 3564 +lj1156.passgo.com - - [08/Mar/2004:09:33:53 -0800] "GET /ops/SP/play//oops/TWiki/TWikiAccessControl HTTP/1.0" 200 209 +64.242.88.10 - - [08/Mar/2004:09:34:58 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiFAQ HTTP/1.1" 200 43115 +64.242.88.10 - - [08/Mar/2004:09:36:35 -0800] "GET /ops/SP/play//edit/TWiki/WebNotification?topicparent=TWiki.TWikiUpgradeTo01May2000 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:09:38:11 -0800] "GET /ops/SP/play//view/Main/TWikiGuest?rev=r1.3 HTTP/1.1" 200 4604 +lj1156.passgo.com - - [08/Mar/2004:09:40:30 -0800] "GET /ops/SP/play//view/TWiki/d43 HTTP/1.0" 200 4619 +64.242.88.10 - - [08/Mar/2004:09:41:15 -0800] "GET /ops/SP/play//edit/Main/Export_environment?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:09:42:27 -0800] "GET /ops/SP/play//rdiff/Know/ReadmeFirst?rev1=1.6&rev2=1.5 HTTP/1.1" 200 4187 +64.242.88.10 - - [08/Mar/2004:09:45:15 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Change%20*Password[^A-Za-z] HTTP/1.1" 200 7226 +64.242.88.10 - - [08/Mar/2004:10:01:06 -0800] "GET /ops/SP/play//view/TWiki/TWikiTopics?rev=r1.4 HTTP/1.1" 200 5171 +64.242.88.10 - - [08/Mar/2004:10:05:40 -0800] "GET /ops/SP/play//view/TWiki/WebSearch?rev=r1.9 HTTP/1.1" 200 9469 +lj1164.passgo.com - - [08/Mar/2004:10:06:28 -0800] "GET /ops/SP/play//view/Main/DCCGraphs HTTP/1.0" 200 5383 +64.242.88.10 - - [08/Mar/2004:10:08:02 -0800] "GET /ops/SP/play//rename/TWiki/DefaultPlugin HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:10:09:52 -0800] "GET /ops/SP/play//view/Main/TWikiGuest?rev=r1.1 HTTP/1.1" 200 3763 +64.242.88.10 - - [08/Mar/2004:10:14:46 -0800] "GET /ops/SP/play//edit/TWiki/TWikiRegistration?t=1078670224 HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:10:16:52 -0800] "GET /ops/SP/play//view/Main/TWikiAdminGroup?rev=1.6 HTTP/1.1" 200 4462 +64.242.88.10 - - [08/Mar/2004:10:18:21 -0800] "GET /ops/SP/play//rdiff/TWiki/WikiSyntax HTTP/1.1" 200 59454 +64.242.88.10 - - [08/Mar/2004:10:21:21 -0800] "GET /ops/SP/play//oops/TWiki/WikiCulture?template=oopsmore¶m1=1.8¶m2=1.8 HTTP/1.1" 200 11245 +64.242.88.10 - - [08/Mar/2004:10:30:56 -0800] "GET /ops/SP/play//view/TWiki/WikiTopic HTTP/1.1" 200 4646 +64.242.88.10 - - [08/Mar/2004:10:32:18 -0800] "GET /ops/SP/play//rdiff/TWiki/WebPreferences HTTP/1.1" 200 36410 +64.242.88.10 - - [08/Mar/2004:10:34:55 -0800] "GET /ops/SP/play//view/TWiki/WebSearch?skin=print HTTP/1.1" 200 7196 +64.242.88.10 - - [08/Mar/2004:10:40:09 -0800] "GET /ops/SP/play//view/TWiki/TWikiTopics?rev=r1.7 HTTP/1.1" 200 8540 +64.242.88.10 - - [08/Mar/2004:10:45:25 -0800] "GET /ops/SP/play//search/Main/SearchResult?scope=text®ex=on&search=Thanadon%20*Somdee[^A-Za-z] HTTP/1.1" 200 4287 +64.242.88.10 - - [08/Mar/2004:10:46:34 -0800] "GET /ops/SP/play//view/TWiki/TWikiUpgradeTo01May2000?rev=1.3 HTTP/1.1" 200 7441 +10.0.0.176 - - [08/Mar/2004:10:48:02 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:10:48:05 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 7213 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 7970 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7254 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8821 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6866 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9312 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6596 +10.0.0.176 - - [08/Mar/2004:10:48:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5499 +64.242.88.10 - - [08/Mar/2004:10:48:19 -0800] "GET /ops/SP/play//edit/Main/Max_use?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/index.jsp HTTP/1.1" 304 - +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3080 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2224 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3299 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2481 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1667 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2346 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1872 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1585 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2202 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1833 +10.0.0.176 - - [08/Mar/2004:10:48:37 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1521 +64.242.88.10 - - [08/Mar/2004:10:50:05 -0800] "GET /ops/SP/play//rdiff/TWiki/WebRss HTTP/1.1" 200 21483 +64.242.88.10 - - [08/Mar/2004:11:03:34 -0800] "GET /ops/SP/play//rdiff/TWiki/WikiCulture?rev1=1.8&rev2=1.7 HTTP/1.1" 200 5326 +128.227.88.79 - - [08/Mar/2004:11:06:20 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +128.227.88.79 - - [08/Mar/2004:11:06:20 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +128.227.88.79 - - [08/Mar/2004:11:06:28 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +64.242.88.10 - - [08/Mar/2004:11:09:24 -0800] "GET /ops/SP/play//edit/Main/Lmtp_mail_timeout?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +128.227.88.79 - - [08/Mar/2004:11:10:09 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +128.227.88.79 - - [08/Mar/2004:11:10:24 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +128.227.88.79 - - [08/Mar/2004:11:11:04 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +128.227.88.79 - - [08/Mar/2004:11:11:10 -0800] "GET /ops/SP/play//view/Main/TWikiGroups HTTP/1.1" 200 4816 +128.227.88.79 - - [08/Mar/2004:11:11:15 -0800] "GET /ops/SP/play//view/Main/TWikiAdminGroup HTTP/1.1" 200 4175 +128.227.88.79 - - [08/Mar/2004:11:11:26 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +64.242.88.10 - - [08/Mar/2004:11:11:51 -0800] "GET /ops/SP/play//edit/Main/TWikiGuest?t=1078713282 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:11:15:51 -0800] "GET /ops/SP/play//rdiff/TWiki/AdminSkillsAssumptions HTTP/1.1" 200 10368 +64.242.88.10 - - [08/Mar/2004:11:17:49 -0800] "GET /ops/SP/play//view/Sandbox/WebHome?rev=r1.3 HTTP/1.1" 200 8708 +64.242.88.10 - - [08/Mar/2004:11:19:43 -0800] "GET /ops/SP/play//edit/TWiki/WikiNotation?t=1078726052 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:11:24:12 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Wiki%20*Notation[^A-Za-z] HTTP/1.1" 200 6558 +64.242.88.10 - - [08/Mar/2004:11:25:16 -0800] "GET /ops/SP/play//oops/TWiki/WikiNotation?template=oopsmore¶m1=1.3¶m2=1.3 HTTP/1.1" 200 11263 +10.0.0.176 - - [08/Mar/2004:11:40:41 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 7226 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 8055 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8787 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7088 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6866 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6596 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9312 +10.0.0.176 - - [08/Mar/2004:11:40:42 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5499 +64.242.88.10 - - [08/Mar/2004:11:41:14 -0800] "GET /mailman/admin/artsscience HTTP/1.1" 200 2125 +64.242.88.10 - - [08/Mar/2004:11:43:17 -0800] "GET /ops/SP/play//search/Main/?scope=topic®ex=on&search=^d HTTP/1.1" 200 5036 +64.242.88.10 - - [08/Mar/2004:11:45:08 -0800] "GET /ops/SP/play//edit/TWiki/TWikiCodevFeatureToDo?topicparent=TWiki.TWikiHistory HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:11:47:52 -0800] "GET /ops/SP/play//rename/TWiki/ResetPassword HTTP/1.1" 401 12851 +64.242.88.10 - - [08/Mar/2004:11:49:23 -0800] "GET /ops/SP/play//edit/Main/Fast_flush_domains?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:11:51:20 -0800] "GET /ops/SP/play//edit/Main/SpamAssassin?t=1078709979 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:11:56:19 -0800] "GET /ops/SP/play//view/TWiki/TWikiTopics?rev=r1.10 HTTP/1.1" 200 14650 +64.242.88.10 - - [08/Mar/2004:11:57:28 -0800] "GET /ops/SP/play//view/TWiki/FileAttribute?rev=r1.2 HTTP/1.1" 200 3949 +64.242.88.10 - - [08/Mar/2004:12:00:26 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiEnhancementRequests HTTP/1.1" 200 10417 +64.242.88.10 - - [08/Mar/2004:12:06:03 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Kevin%20*Kinnell[^A-Za-z] HTTP/1.1" 200 4536 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 7192 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 8081 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 9065 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7206 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9312 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6866 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6596 +10.0.0.176 - - [08/Mar/2004:12:06:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5499 +64.242.88.10 - - [08/Mar/2004:12:07:13 -0800] "GET /ops/SP/play//view/TWiki/FileAttribute?rev=1.2 HTTP/1.1" 200 3949 +64.242.88.10 - - [08/Mar/2004:12:08:32 -0800] "GET /ops/SP/play//view/TWiki/WikiNotation?skin=print HTTP/1.1" 200 1435 +64.242.88.10 - - [08/Mar/2004:12:10:39 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiPlannedFeatures HTTP/1.1" 200 10577 +64.242.88.10 - - [08/Mar/2004:12:12:50 -0800] "GET /mailman/admin/deans HTTP/1.1" 200 2080 +64.242.88.10 - - [08/Mar/2004:12:15:36 -0800] "GET /pipermail/webber/ HTTP/1.1" 200 1161 +64.242.88.10 - - [08/Mar/2004:12:20:18 -0800] "GET /ops/SP/play//view/Main/PostSuper?rev=1.1 HTTP/1.1" 200 3629 +64.242.88.10 - - [08/Mar/2004:12:25:47 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=1.13 HTTP/1.1" 200 8770 +64.242.88.10 - - [08/Mar/2004:12:28:09 -0800] "GET /ops/SP/play//edit/Main/Mailq_path?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:12:31:32 -0800] "GET /ops/SP/play//view/TWiki/WebHome?rev=r1.49 HTTP/1.1" 200 12993 +64.242.88.10 - - [08/Mar/2004:12:33:09 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=r1.49 HTTP/1.1" 200 42243 +64.242.88.10 - - [08/Mar/2004:12:39:34 -0800] "GET /ops/SP/play//rdiff/TWiki/TWikiDocGraphics?rev1=1.11&rev2=1.10 HTTP/1.1" 200 6551 +64.242.88.10 - - [08/Mar/2004:12:40:36 -0800] "GET /ops/SP/play//view/TWiki/WebHome?rev=r1.47 HTTP/1.1" 200 12819 +64.242.88.10 - - [08/Mar/2004:12:42:04 -0800] "GET /ops/SP/play//view/Sandbox/WebStatistics HTTP/1.1" 200 6063 +64.242.88.10 - - [08/Mar/2004:12:43:08 -0800] "GET /pipermail/gisgrad/ HTTP/1.1" 200 1118 +64.242.88.10 - - [08/Mar/2004:12:45:13 -0800] "GET /mailman/admin/webber HTTP/1.1" 200 2089 +64.242.88.10 - - [08/Mar/2004:12:47:42 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=1.14 HTTP/1.1" 200 8820 +64.242.88.10 - - [08/Mar/2004:12:55:18 -0800] "GET /ops/SP/play//view/TWiki/KevinKinnell?rev=1.4 HTTP/1.1" 200 3730 +64.242.88.10 - - [08/Mar/2004:12:58:39 -0800] "GET /ops/SP/play//search/Main/?search=\\.*&scope=topic&order=modified&reverse=on®ex=on&nosearch=on&limit=800 HTTP/1.1" 200 43915 +market-mail.panduit.com - - [08/Mar/2004:12:58:50 -0800] "GET / HTTP/1.0" 200 3169 +market-mail.panduit.com - - [08/Mar/2004:12:58:50 -0800] "GET /favicon.ico HTTP/1.0" 200 1078 +market-mail.panduit.com - - [08/Mar/2004:12:59:18 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +market-mail.panduit.com - - [08/Mar/2004:12:59:34 -0800] "GET /ststats/index.jsp HTTP/1.0" 200 2955 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.0" 200 3095 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.0" 200 2272 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.0" 200 3279 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.0" 200 2349 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.0" 200 1659 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.0" 200 2542 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.0" 200 1927 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.0" 200 1580 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.0" 200 2201 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.0" 200 1829 +market-mail.panduit.com - - [08/Mar/2004:12:59:37 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.0" 200 1524 +market-mail.panduit.com - - [08/Mar/2004:12:59:55 -0800] "GET /DCC.jsp HTTP/1.0" 200 2878 +market-mail.panduit.com - - [08/Mar/2004:13:00:12 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +market-mail.panduit.com - - [08/Mar/2004:13:00:12 -0800] "GET /favicon.ico HTTP/1.0" 200 1078 +market-mail.panduit.com - - [08/Mar/2004:13:00:13 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +market-mail.panduit.com - - [08/Mar/2004:13:00:20 -0800] "GET /ops/SP/play//view/Main/DCC HTTP/1.0" 200 4377 +market-mail.panduit.com - - [08/Mar/2004:13:00:27 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.0" 200 5234 +64.242.88.10 - - [08/Mar/2004:13:00:40 -0800] "GET /ops/SP/play//oops/TWiki/HaroldGottschalk?template=oopsmore¶m1=1.3¶m2=1.3 HTTP/1.1" 200 11335 +market-mail.panduit.com - - [08/Mar/2004:13:01:27 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.0" 200 4004 +market-mail.panduit.com - - [08/Mar/2004:13:01:29 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.0" 200 4154 +market-mail.panduit.com - - [08/Mar/2004:13:01:35 -0800] "GET /ops/SP/play//edit/Main/PostConf?topicparent=Main.PostfixCommands HTTP/1.0" 401 12816 +market-mail.panduit.com - - [08/Mar/2004:13:01:38 -0800] "GET /go/bin/test/TWikiDocGraphics/help.gif HTTP/1.0" 200 130 +64.242.88.10 - - [08/Mar/2004:13:01:42 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=John%20*Talintyre[^A-Za-z] HTTP/1.1" 200 8066 +market-mail.panduit.com - - [08/Mar/2004:13:01:42 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.0" 200 3617 +market-mail.panduit.com - - [08/Mar/2004:13:01:55 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.0" 200 4213 +market-mail.panduit.com - - [08/Mar/2004:13:02:03 -0800] "GET /ops/SP/play//view/Main/VerifingGatway HTTP/1.0" 200 4731 +market-mail.panduit.com - - [08/Mar/2004:13:02:16 -0800] "GET /ops/SP/play//view/Main/Relay_Domains HTTP/1.0" 200 4564 +64.242.88.10 - - [08/Mar/2004:13:04:14 -0800] "GET /ops/SP/play//attach/Main/TWikiGuest HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:07:16 -0800] "GET /ops/SP/play//view/Main/NicholasLee?rev=1.1 HTTP/1.1" 200 4456 +64.242.88.10 - - [08/Mar/2004:13:08:17 -0800] "GET /ops/SP/play//attach/TWiki/TWikiDocGraphics?filename=pencil.gif&revInfo=1 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:12:54 -0800] "GET /ops/SP/play//rdiff/TWiki/WebSiteTools?rev1=1.2&rev2=1.1 HTTP/1.1" 200 6640 +64.242.88.10 - - [08/Mar/2004:13:15:03 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=r1.55 HTTP/1.1" 200 44652 +64.242.88.10 - - [08/Mar/2004:13:16:11 -0800] "GET /ops/SP/play//attach/Main/SpamAssassinAndPostFix HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:17:23 -0800] "GET /mailman/private/artsscience/ HTTP/1.1" 200 1552 +64.242.88.10 - - [08/Mar/2004:13:18:57 -0800] "GET /ops/SP/play//search/TWiki/?scope=topic®ex=on&search=^l HTTP/1.1" 200 2937 +64.242.88.10 - - [08/Mar/2004:13:24:49 -0800] "GET /ops/SP/play//rdiff/Main/RelayGateway?rev1=1.3&rev2=1.2 HTTP/1.1" 200 5181 +64.242.88.10 - - [08/Mar/2004:13:29:37 -0800] "GET /ops/SP/play//rdiff/Main/RelayGateway?rev1=1.2&rev2=1.1 HTTP/1.1" 200 6029 +64.242.88.10 - - [08/Mar/2004:13:31:16 -0800] "GET /ops/SP/play//rdiff/TWiki/WikiReferences?rev1=1.2&rev2=1.1 HTTP/1.1" 200 10024 +64.242.88.10 - - [08/Mar/2004:13:32:35 -0800] "GET /ops/SP/play//view/Main/WebPreferences?rev=r1.9 HTTP/1.1" 200 7511 +64.242.88.10 - - [08/Mar/2004:13:35:02 -0800] "GET /ops/SP/play//edit/TWiki/WebSiteTools?t=1078731408 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:36:06 -0800] "GET /ops/SP/play//attach/TWiki/TWikiDocGraphics?filename=viewtopic.gif&revInfo=1 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:38:39 -0800] "GET /ops/SP/play//view/TWiki/SvenDowideit?rev=r1.1 HTTP/1.1" 200 3564 +64.242.88.10 - - [08/Mar/2004:13:45:46 -0800] "GET /ops/SP/play//edit/Main/Ignore_mx_lookup_error?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:48:06 -0800] "GET /ops/SP/play//oops/Main/DCCAndPostFix?template=oopsmore¶m1=1.2¶m2=1.2 HTTP/1.1" 200 6602 +64.242.88.10 - - [08/Mar/2004:13:49:47 -0800] "GET /ops/SP/play//view/TWiki/TWikiHistory?rev=r1.54 HTTP/1.1" 200 44644 +64.242.88.10 - - [08/Mar/2004:13:55:51 -0800] "GET /ops/SP/play//edit/Main/Allow_min_user?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:56:52 -0800] "GET /ops/SP/play//edit/TWiki/KevinKinnell?t=1078692967 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:13:57:52 -0800] "GET /pipermail/fcd/ HTTP/1.1" 200 468 +64.242.88.10 - - [08/Mar/2004:13:58:55 -0800] "GET /mailman/listinfo/mgt-157 HTTP/1.1" 200 6189 +64.242.88.10 - - [08/Mar/2004:14:00:08 -0800] "GET /mailman/admin/fcd HTTP/1.1" 200 2060 +64.242.88.10 - - [08/Mar/2004:14:01:36 -0800] "GET /mailman/listinfo/cnc_forestry HTTP/1.1" 200 6159 +64.242.88.10 - - [08/Mar/2004:14:07:26 -0800] "GET /ops/SP/play//edit/Main/Strict_8bitmime?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:14:11:28 -0800] "GET /ops/SP/play//view/TWiki/WelcomeGuest?rev=r1.19 HTTP/1.1" 200 13997 +64.242.88.10 - - [08/Mar/2004:14:12:49 -0800] "GET /ops/SP/play//view/TWiki/TWikiFAQ?rev=1.11 HTTP/1.1" 200 11950 +64.242.88.10 - - [08/Mar/2004:14:13:51 -0800] "GET /mailman/admin/gisgrad HTTP/1.1" 200 2093 +64.242.88.10 - - [08/Mar/2004:14:15:01 -0800] "GET /mailman/admin/jjec HTTP/1.1" 200 2088 +fw.aub.dk - - [08/Mar/2004:14:16:38 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +fw.aub.dk - - [08/Mar/2004:14:16:39 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +64.242.88.10 - - [08/Mar/2004:14:23:54 -0800] "GET /ops/SP/play//oops/TWiki/RyanFreebern?template=oopsmore¶m1=1.2¶m2=1.2 HTTP/1.1" 200 11263 +64.242.88.10 - - [08/Mar/2004:14:25:33 -0800] "GET /ops/SP/play//rdiff/TWiki/WebChangesAlert HTTP/1.1" 200 27035 +64.242.88.10 - - [08/Mar/2004:14:26:45 -0800] "GET /ops/SP/play//rdiff/Sandbox/WebTopicList HTTP/1.1" 200 4319 +64.242.88.10 - - [08/Mar/2004:14:27:46 -0800] "GET /ops/SP/play//edit/Main/Virtual_gid_maps?topicparent=Main.ConfigurationVariables HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:14:28:46 -0800] "GET /ops/SP/play//view/TWiki/NewUserTemplate?skin=print HTTP/1.1" 200 2449 +64.242.88.10 - - [08/Mar/2004:14:33:56 -0800] "GET /mailman/admin HTTP/1.1" 200 6872 +64.242.88.10 - - [08/Mar/2004:14:40:18 -0800] "GET /mailman/admin/ncbnpfaculty HTTP/1.1" 200 2136 +64.242.88.10 - - [08/Mar/2004:14:41:22 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Web%20*Topic%20*List[^A-Za-z] HTTP/1.1" 200 10700 +64.242.88.10 - - [08/Mar/2004:14:42:44 -0800] "GET /ops/SP/play//view/TWiki/WebSearch?rev=1.11 HTTP/1.1" 200 9419 +64.242.88.10 - - [08/Mar/2004:14:43:45 -0800] "GET /ops/SP/play//view/TWiki/MartinCleaver HTTP/1.1" 200 3634 +64.242.88.10 - - [08/Mar/2004:14:52:51 -0800] "GET /ops/SP/play//view/TWiki/WebIndex HTTP/1.1" 200 102154 +64.242.88.10 - - [08/Mar/2004:14:54:56 -0800] "GET /ops/SP/play//edit/Main/TokyoOffice?t=1078706364 HTTP/1.1" 401 12846 +64.242.88.10 - - [08/Mar/2004:14:57:19 -0800] "GET /ops/SP/play//rdiff/Main/SpamAssassinAndPostFix?rev1=1.2&rev2=1.1 HTTP/1.1" 200 5794 +64.242.88.10 - - [08/Mar/2004:14:58:58 -0800] "GET /ops/SP/play//rdiff/TWiki/WhatIsWikiWiki HTTP/1.1" 200 9412 +64.242.88.10 - - [08/Mar/2004:15:00:07 -0800] "GET /ops/SP/play//rdiff/Main/WebChanges?rev1=1.2&rev2=1.1 HTTP/1.1" 200 114220 +64.242.88.10 - - [08/Mar/2004:15:01:12 -0800] "GET /ops/SP/play//rdiff/TWiki/EditDoesNotIncreaseTheRevision HTTP/1.1" 200 6310 +64.242.88.10 - - [08/Mar/2004:15:02:29 -0800] "GET /ops/SP/play//rdiff/TWiki/WebTopicList HTTP/1.1" 200 14591 +64.242.88.10 - - [08/Mar/2004:15:03:49 -0800] "GET /antivirus.jsp HTTP/1.1" 200 3548 +64.242.88.10 - - [08/Mar/2004:15:07:41 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Harold%20*Gottschalk[^A-Za-z] HTTP/1.1" 200 4412 +ip-200-56-225-61-mty.marcatel.net.mx - - [08/Mar/2004:15:15:17 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +64.242.88.10 - - [08/Mar/2004:15:16:14 -0800] "GET /ops/SP/play//view/TWiki/TextFormattingRules?rev=r1.37 HTTP/1.1" 200 28922 +64.242.88.10 - - [08/Mar/2004:15:17:18 -0800] "GET /ops/SP/play//search/Main/?scope=topic®ex=on&search=^f HTTP/1.1" 200 3438 +64.242.88.10 - - [08/Mar/2004:15:19:35 -0800] "GET /RBL.jsp HTTP/1.1" 200 4114 +c-24-11-14-147.client.comcast.net - - [08/Mar/2004:16:54:47 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +c-24-11-14-147.client.comcast.net - - [08/Mar/2004:16:54:47 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +lj1036.passgo.com - - [08/Mar/2004:17:39:00 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1168.passgo.com - - [08/Mar/2004:17:39:01 -0800] "GET /ops/SP/play//oops/TWiki/TWikiVariables HTTP/1.0" 200 209 +calcite.rhyolite.com - - [08/Mar/2004:18:14:44 -0800] "GET /clients.jsp HTTP/1.1" 200 18767 +acbf6930.ipt.aol.com - - [08/Mar/2004:18:20:44 -0800] "GET /RBL.jsp HTTP/1.1" 200 4114 +acbf6930.ipt.aol.com - - [08/Mar/2004:18:20:44 -0800] "GET /LateEmail.jsp HTTP/1.1" 200 7649 +lj1018.passgo.com - - [08/Mar/2004:18:23:43 -0800] "GET /ops/SP/play//oops/Know/PublicSupported HTTP/1.0" 200 209 +barrie-ppp108371.sympatico.ca - - [08/Mar/2004:18:39:33 -0800] "GET /mailman/listinfo/webber HTTP/1.1" 200 6051 +barrie-ppp108371.sympatico.ca - - [08/Mar/2004:18:39:35 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +barrie-ppp108371.sympatico.ca - - [08/Mar/2004:18:39:35 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +barrie-ppp108371.sympatico.ca - - [08/Mar/2004:18:39:36 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +px7wh.vc.shawcable.net - - [08/Mar/2004:18:41:16 -0800] "GET /LateEmail.jsp HTTP/1.1" 200 7649 +user-0c8hdkf.cable.mindspring.com - - [08/Mar/2004:19:08:27 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +user-0c8hdkf.cable.mindspring.com - - [08/Mar/2004:19:08:28 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +user-0c8hdkf.cable.mindspring.com - - [08/Mar/2004:19:08:39 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.1" 200 4232 +user-0c8hdkf.cable.mindspring.com - - [08/Mar/2004:19:08:52 -0800] "GET /ops/SP/play//view/Main/VerifingGatway HTTP/1.1" 200 4750 +user-0c8hdkf.cable.mindspring.com - - [08/Mar/2004:19:10:06 -0800] "GET /ops/SP/play//view/Main/Relay_Domains HTTP/1.1" 200 4583 +lj1053.passgo.com - - [08/Mar/2004:19:24:42 -0800] "GET /ops/SP/play//oops/Main/SpamAssassinTaggingOnly HTTP/1.0" 200 209 +64.246.94.152 - - [08/Mar/2004:20:09:57 -0800] "HEAD /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 0 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:18 -0800] "GET / HTTP/1.0" 200 3169 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:18 -0800] "GET /favicon.ico HTTP/1.0" 200 1078 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:25 -0800] "GET /ststats/index.jsp HTTP/1.0" 200 2955 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.0" 200 3049 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.0" 200 2160 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.0" 200 2386 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.0" 200 3271 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.0" 200 1687 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:26 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.0" 200 2482 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:27 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.0" 200 1914 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:27 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.0" 200 1536 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:27 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.0" 200 2250 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:27 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.0" 200 1883 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:27 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.0" 200 1493 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:48 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:49 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:49 -0800] "GET /favicon.ico HTTP/1.0" 200 1078 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:48:53 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.0" 200 5234 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:50:59 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.0" 200 4022 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:51:01 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.0" 200 5672 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:51:51 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.0" 200 4062 +ip68-228-43-49.tc.ph.cox.net - - [08/Mar/2004:20:52:01 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.0" 200 4062 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:04 -0800] "GET / HTTP/1.0" 200 3169 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:28 -0800] "GET /ststats/index.jsp HTTP/1.0" 200 2955 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.0" 200 3238 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.0" 200 3032 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.0" 200 2160 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.0" 200 2369 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.0" 200 1671 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.0" 200 2485 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.0" 200 1533 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.0" 200 1906 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.0" 200 2251 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.0" 200 1875 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:29 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.0" 200 1483 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:44 -0800] "GET /SpamAssassin.jsp HTTP/1.0" 200 7368 +proxy0.haifa.ac.il - - [08/Mar/2004:22:03:52 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +proxy0.haifa.ac.il - - [08/Mar/2004:22:04:09 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +proxy0.haifa.ac.il - - [08/Mar/2004:22:04:10 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +proxy0.haifa.ac.il - - [08/Mar/2004:22:04:24 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.0" 200 4515 +proxy0.haifa.ac.il - - [08/Mar/2004:22:04:35 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.0" 200 4004 +alille-251-1-2-197.w82-124.abo.wanadoo.fr - - [08/Mar/2004:22:30:01 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +a213-84-36-192.adsl.xs4all.nl - - [08/Mar/2004:23:42:55 -0800] "GET / HTTP/1.1" 200 3169 +195.246.13.119 - - [09/Mar/2004:01:48:27 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +195.246.13.119 - - [09/Mar/2004:01:48:28 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +195.246.13.119 - - [09/Mar/2004:01:48:28 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +195.246.13.119 - - [09/Mar/2004:01:49:53 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +195.246.13.119 - - [09/Mar/2004:01:49:57 -0800] "GET /ops/SP/play//view/Main/KevinWGagel HTTP/1.1" 200 4901 +195.246.13.119 - - [09/Mar/2004:01:50:35 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +195.246.13.119 - - [09/Mar/2004:01:50:54 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +195.246.13.119 - - [09/Mar/2004:01:51:17 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +195.246.13.119 - - [09/Mar/2004:01:51:41 -0800] "GET /ops/SP/play//edit/Main/RazorAndPostFix?topicparent=Main.WebHome HTTP/1.1" 401 12851 +195.246.13.119 - - [09/Mar/2004:01:51:45 -0800] "GET /go/bin/test/TWikiDocGraphics/help.gif HTTP/1.1" 200 130 +195.246.13.119 - - [09/Mar/2004:01:51:54 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.1" 200 4232 +195.246.13.119 - - [09/Mar/2004:01:52:12 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.1" 200 4534 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:10 -0800] "GET /ststats/index.jsp HTTP/1.1" 200 2955 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:17 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3068 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:17 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2187 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:17 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3277 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:17 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2379 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1687 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2592 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1983 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1545 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2222 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1866 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1494 +200-55-104-193.dsl.prima.net.ar - - [09/Mar/2004:02:33:18 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +lj1052.passgo.com - - [09/Mar/2004:02:39:17 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1162.passgo.com - - [09/Mar/2004:02:39:18 -0800] "GET /ops/SP/play//view/Main/SanJoseOffice HTTP/1.0" 200 3884 +lj1162.passgo.com - - [09/Mar/2004:03:10:39 -0800] "GET /ops/SP/play//view/Main/SanJoseOffice HTTP/1.0" 200 3884 +mail.geovariances.fr - - [09/Mar/2004:05:01:53 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +mail.geovariances.fr - - [09/Mar/2004:05:01:53 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +mail.geovariances.fr - - [09/Mar/2004:05:02:11 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.1" 200 4081 +mail.geovariances.fr - - [09/Mar/2004:05:02:11 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:02:14 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +mail.geovariances.fr - - [09/Mar/2004:05:02:14 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:02:19 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +mail.geovariances.fr - - [09/Mar/2004:05:02:19 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:02:27 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +mail.geovariances.fr - - [09/Mar/2004:05:02:28 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:04:09 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +mail.geovariances.fr - - [09/Mar/2004:05:04:09 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:09:30 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +mail.geovariances.fr - - [09/Mar/2004:05:09:31 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:12:45 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:12:45 -0800] "GET /ops/SP/play//view/Main/ConfigurationVariables HTTP/1.1" 200 58292 +mail.geovariances.fr - - [09/Mar/2004:05:13:40 -0800] "GET /ops/SP/play//view/TWiki/WebHome HTTP/1.1" 200 15182 +mail.geovariances.fr - - [09/Mar/2004:05:13:40 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +mail.geovariances.fr - - [09/Mar/2004:05:13:40 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot131x64.gif HTTP/1.1" 200 7218 +mail.geovariances.fr - - [09/Mar/2004:05:13:40 -0800] "GET /go/bin/test/TWikiDocGraphics/tip.gif HTTP/1.1" 200 123 +mail.geovariances.fr - - [09/Mar/2004:05:13:40 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot88x31.gif HTTP/1.1" 200 3501 +mail.geovariances.fr - - [09/Mar/2004:05:14:13 -0800] "GET /ops/SP/play//view/Sandbox/WebHome HTTP/1.1" 200 8632 +mail.geovariances.fr - - [09/Mar/2004:05:14:14 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +66-194-6-70.gen.twtelecom.net - - [09/Mar/2004:05:20:20 -0800] "GET / HTTP/1.1" 200 3169 +195.230.181.122 - - [09/Mar/2004:06:29:03 -0800] "GET /AmavisNew.jsp HTTP/1.0" 200 2300 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:33:21 -0800] "GET / HTTP/1.1" 200 3169 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:51 -0800] "GET /ststats/index.jsp HTTP/1.1" 200 2955 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:53 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3027 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:53 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2148 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:54 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3200 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:54 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2341 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:55 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1686 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:55 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2534 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:56 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1948 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:56 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1549 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:57 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2214 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:57 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1873 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:34:58 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1500 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:04 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6708 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:06 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 8232 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:09 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8857 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:10 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7175 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:13 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9391 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:13 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6922 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:17 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6618 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:17 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5615 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:35:42 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:36:28 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:36:29 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:36:51 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:37:00 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +ts04-ip92.hevanet.com - - [09/Mar/2004:06:37:40 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:10 -0800] "GET / HTTP/1.1" 200 3169 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:10 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:44 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:44 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:44 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:27:59 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:28:05 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:07:28:12 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +207.195.59.160 - - [09/Mar/2004:08:08:35 -0800] "GET / HTTP/1.1" 200 3169 +207.195.59.160 - - [09/Mar/2004:08:08:37 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +207.195.59.160 - - [09/Mar/2004:08:08:38 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +207.195.59.160 - - [09/Mar/2004:08:08:54 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +207.195.59.160 - - [09/Mar/2004:08:08:54 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +207.195.59.160 - - [09/Mar/2004:08:08:57 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +207.195.59.160 - - [09/Mar/2004:08:09:39 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.1" 200 4665 +207.195.59.160 - - [09/Mar/2004:08:09:39 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +207.195.59.160 - - [09/Mar/2004:08:09:58 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +207.195.59.160 - - [09/Mar/2004:08:09:58 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +207.195.59.160 - - [09/Mar/2004:08:10:04 -0800] "GET /ops/SP/play//edit/Main/PostConf?topicparent=Main.PostfixCommands HTTP/1.1" 401 12851 +207.195.59.160 - - [09/Mar/2004:08:10:06 -0800] "GET /go/bin/test/TWikiDocGraphics/help.gif HTTP/1.1" 200 130 +207.195.59.160 - - [09/Mar/2004:08:10:12 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.1" 200 4232 +207.195.59.160 - - [09/Mar/2004:08:10:12 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +207.195.59.160 - - [09/Mar/2004:08:10:20 -0800] "GET /ops/SP/play//view/Main/Relay_Domains HTTP/1.1" 200 4583 +fw1.millardref.com - - [09/Mar/2004:08:17:27 -0800] "GET / HTTP/1.1" 200 3169 +207.195.59.160 - - [09/Mar/2004:08:17:34 -0800] "GET /ops/SP/play//view/Main/VerifingGatway HTTP/1.1" 200 4750 +fw1.millardref.com - - [09/Mar/2004:08:17:50 -0800] "GET /RBL.jsp HTTP/1.1" 200 4114 +207.195.59.160 - - [09/Mar/2004:08:18:17 -0800] "GET /ops/SP/play//view/Main/SideBar HTTP/1.1" 200 3972 +207.195.59.160 - - [09/Mar/2004:08:18:17 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +fw1.millardref.com - - [09/Mar/2004:08:18:19 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +fw1.millardref.com - - [09/Mar/2004:08:18:25 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +fw1.millardref.com - - [09/Mar/2004:08:18:26 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +fw1.millardref.com - - [09/Mar/2004:08:18:27 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +fw1.millardref.com - - [09/Mar/2004:08:18:27 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +207.195.59.160 - - [09/Mar/2004:08:18:50 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +207.195.59.160 - - [09/Mar/2004:08:19:04 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +lj1007.passgo.com - - [09/Mar/2004:09:55:44 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1125.passgo.com - - [09/Mar/2004:09:55:53 -0800] "GET /ops/SP/play//oops/TWiki/WebChangesAlert HTTP/1.0" 200 209 +80.58.35.111.proxycache.rima-tde.net - - [09/Mar/2004:10:08:07 -0800] "GET /RBL.jsp HTTP/1.0" 200 4114 +10.0.0.176 - - [09/Mar/2004:10:29:38 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [09/Mar/2004:10:29:40 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8830 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 7255 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6703 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7127 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9241 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6856 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6618 +10.0.0.176 - - [09/Mar/2004:10:29:41 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5615 +200.222.33.33 - - [09/Mar/2004:11:21:36 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +1-320.tnr.on.ca - - [09/Mar/2004:11:43:54 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +1-320.tnr.on.ca - - [09/Mar/2004:11:43:56 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +1-320.tnr.on.ca - - [09/Mar/2004:11:43:56 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +1-320.tnr.on.ca - - [09/Mar/2004:11:43:56 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +l07v-1-17.d1.club-internet.fr - - [09/Mar/2004:11:57:20 -0800] "GET / HTTP/1.1" 200 3169 +wwwcache.lanl.gov - - [09/Mar/2004:12:16:06 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +trrc02m01-40.bctel.ca - - [09/Mar/2004:12:21:08 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +trrc02m01-40.bctel.ca - - [09/Mar/2004:12:21:09 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +trrc02m01-40.bctel.ca - - [09/Mar/2004:12:21:09 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +trrc02m01-40.bctel.ca - - [09/Mar/2004:12:21:10 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +fw.kcm.org - - [09/Mar/2004:12:21:49 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +fw.kcm.org - - [09/Mar/2004:12:21:49 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +lj1048.passgo.com - - [09/Mar/2004:12:52:21 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1031.passgo.com - - [09/Mar/2004:12:52:58 -0800] "GET /ops/SP/play//oops/TWiki/InterwikiPlugin HTTP/1.0" 200 209 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:14:53 -0800] "GET / HTTP/1.1" 200 3169 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:15:15 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:15:15 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:15:23 -0800] "GET /ops/SP/play//view/Main/SpamAssassin HTTP/1.1" 200 4081 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:15:33 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:15:49 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +c-24-20-163-223.client.comcast.net - - [09/Mar/2004:13:16:00 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +h194n2fls308o1033.telia.com - - [09/Mar/2004:13:49:05 -0800] "-" 408 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:02 -0800] "GET /mailman HTTP/1.1" 302 301 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:03 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:04 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:05 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:05 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:14:43:12 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:15 -0800] "GET / HTTP/1.1" 200 3169 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:23 -0800] "GET /mailman HTTP/1.1" 302 301 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:23 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:24 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:24 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:24 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:50:28 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +jacksonproject.tnr.on.ca - - [09/Mar/2004:14:56:15 -0800] "GET / HTTP/1.1" 304 - +home.yeungs.net - - [09/Mar/2004:15:03:55 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +203.147.138.233 - - [09/Mar/2004:15:25:03 -0800] "GET /ststats/index.jsp HTTP/1.1" 200 2955 +203.147.138.233 - - [09/Mar/2004:15:25:05 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +203.147.138.233 - - [09/Mar/2004:15:25:14 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3041 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1695 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2577 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3203 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1970 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2181 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1550 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2314 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1850 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2213 +203.147.138.233 - - [09/Mar/2004:15:25:15 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1509 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:37:35 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:37:36 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:37:36 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:37:36 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:15:44:52 -0800] "GET / HTTP/1.1" 200 3169 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:15:44:52 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +208-38-57-205.ip.cal.radiant.net - - [09/Mar/2004:15:44:57 -0800] "GET /rejected.jsp HTTP/1.1" 200 3998 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:51:10 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 2082 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:51:24 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 2182 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:52:09 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 2182 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:52:15 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 19597 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:53:40 -0800] "GET /mailman/admin/ppwc/logout HTTP/1.1" 200 2103 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:53:49 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +h24-71-236-129.ca.clawio.org - - [09/Mar/2004:15:53:56 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +lj1123.passgo.com - - [09/Mar/2004:16:23:55 -0800] "GET /ops/SP/play//oops/TWiki/RegularExp HTTP/1.0" 200 209 +206-15-133-153.dialup.ziplink.net - - [09/Mar/2004:16:27:48 -0800] "HEAD /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 0 +lj1048.passgo.com - - [09/Mar/2004:17:10:26 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1061.passgo.com - - [09/Mar/2004:17:10:28 -0800] "GET /ops/SP/play//oops/TWiki/TablePlugin HTTP/1.0" 200 209 +korell2.cc.gatech.edu - - [09/Mar/2004:17:33:58 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +65-37-13-251.nrp2.roc.ny.frontiernet.net - - [09/Mar/2004:17:42:41 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +65-37-13-251.nrp2.roc.ny.frontiernet.net - - [09/Mar/2004:17:42:42 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +65-37-13-251.nrp2.roc.ny.frontiernet.net - - [09/Mar/2004:17:42:42 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +65-37-13-251.nrp2.roc.ny.frontiernet.net - - [09/Mar/2004:17:43:54 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.1" 200 4665 +65-37-13-251.nrp2.roc.ny.frontiernet.net - - [09/Mar/2004:17:45:02 -0800] "GET /ops/SP/play//view/Sandbox/WebHome HTTP/1.1" 200 8632 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:00:43 -0800] "GET /mailman/admin HTTP/1.1" 200 6872 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:00:44 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:00:44 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:00:44 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:01:11 -0800] "GET /mailman/admin/webct HTTP/1.1" 200 2080 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:01:24 -0800] "GET /mailman HTTP/1.1" 302 301 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:01:25 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:01:28 -0800] "GET /mailman/listinfo/administration HTTP/1.1" 200 6459 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:01:45 -0800] "GET /mailman/listinfo/cnc_notice HTTP/1.1" 200 6337 +cpe-203-51-137-224.vic.bigpond.net.au - - [09/Mar/2004:18:02:07 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +grandpa.mmlc.northwestern.edu - - [09/Mar/2004:18:06:27 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +grandpa.mmlc.northwestern.edu - - [09/Mar/2004:18:06:27 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:23:32 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:23:32 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:25:15 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:25:18 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +calcite.rhyolite.com - - [09/Mar/2004:20:34:55 -0800] "GET /clients.jsp HTTP/1.1" 200 18892 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:45:43 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:45:48 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +mth-fgw.ballarat.edu.au - - [09/Mar/2004:20:45:51 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +2-238.tnr.on.ca - - [09/Mar/2004:21:33:22 -0800] "GET / HTTP/1.1" 200 3169 +lj1048.passgo.com - - [09/Mar/2004:21:51:09 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1153.passgo.com - - [09/Mar/2004:21:51:16 -0800] "GET /ops/SP/play//oops/Main/ThanadonSomdee HTTP/1.0" 200 209 +mmscrm07-2.uah.goweb.net - - [09/Mar/2004:22:23:39 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1036.passgo.com - - [09/Mar/2004:22:31:21 -0800] "GET /ops/SP/play//oops/Know/TopicClassification HTTP/1.0" 200 209 +adsl-157-26-153.msy.bellsouth.net - - [09/Mar/2004:22:40:32 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +adsl-157-26-153.msy.bellsouth.net - - [09/Mar/2004:22:40:33 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +lj1164.passgo.com - - [09/Mar/2004:22:44:31 -0800] "GET /ops/SP/play//oops/TWiki/TextFormattingRules HTTP/1.0" 200 209 +66-194-6-79.gen.twtelecom.net - - [09/Mar/2004:23:36:11 -0800] "GET / HTTP/1.1" 200 3169 +lj1231.passgo.com - - [10/Mar/2004:00:21:51 -0800] "GET /ops/SP/play//oops/Main/TWikiUsers HTTP/1.0" 200 209 +212.21.228.26 - - [10/Mar/2004:00:24:58 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +yongsan-cache.korea.army.mil - - [10/Mar/2004:00:29:44 -0800] "GET /mailman/listinfo/cncce HTTP/1.1" 200 6208 +yongsan-cache.korea.army.mil - - [10/Mar/2004:00:29:44 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +yongsan-cache.korea.army.mil - - [10/Mar/2004:00:29:44 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +yongsan-cache.korea.army.mil - - [10/Mar/2004:00:29:45 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +pd9e761cf.dip.t-dialin.net - - [10/Mar/2004:02:07:27 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +lj1048.passgo.com - - [10/Mar/2004:02:31:33 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1160.passgo.com - - [10/Mar/2004:02:31:44 -0800] "GET /razor.jsp HTTP/1.0" 304 - +nb-bolz.cremona.polimi.it - - [10/Mar/2004:02:52:49 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +pc-030-040.eco.rug.nl - - [10/Mar/2004:02:55:00 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:11:40 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:11:50 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:11:53 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:07 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:20 -0800] "GET /ops/SP/play//view/Main/ConfigurationVariables HTTP/1.1" 200 58292 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:33 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.1" 200 4665 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:45 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:48 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.1" 200 3629 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:12:56 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.1" 200 4534 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:14:40 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:14:54 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:15:28 -0800] "GET /ops/SP/play//view/Main/SideBar HTTP/1.1" 200 3972 +pc3-registry-stockholm.telia.net - - [10/Mar/2004:03:15:33 -0800] "GET /ops/SP/play//view/Main/DCCGraphs HTTP/1.1" 200 5402 +80.58.14.235.proxycache.rima-tde.net - - [10/Mar/2004:03:52:49 -0800] "GET /mailman/listinfo/fnac HTTP/1.0" 200 5969 +80.58.14.235.proxycache.rima-tde.net - - [10/Mar/2004:03:52:51 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +80.58.14.235.proxycache.rima-tde.net - - [10/Mar/2004:03:52:51 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +80.58.14.235.proxycache.rima-tde.net - - [10/Mar/2004:03:52:52 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +66-194-6-70.gen.twtelecom.net - - [10/Mar/2004:05:21:38 -0800] "GET / HTTP/1.1" 200 3169 +pd9e50809.dip.t-dialin.net - - [10/Mar/2004:07:36:56 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +10.0.0.176 - - [10/Mar/2004:08:36:28 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:08:36:30 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 7783 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8845 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6274 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7071 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9328 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6976 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +10.0.0.176 - - [10/Mar/2004:08:36:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +10.0.0.176 - - [10/Mar/2004:08:36:57 -0800] "GET /ststats/index.jsp HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3020 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2287 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2332 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1673 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2583 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 1976 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3364 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2220 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1627 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1837 +10.0.0.176 - - [10/Mar/2004:08:36:58 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1528 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:51:31 -0800] "GET / HTTP/1.1" 304 - +ts05-ip44.hevanet.com - - [10/Mar/2004:08:52:13 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:52:16 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ts05-ip44.hevanet.com - - [10/Mar/2004:08:52:25 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.1" 200 5253 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:52:52 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:53:12 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:53:19 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.1" 200 4173 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:53:33 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.1" 200 3629 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:54:15 -0800] "GET /ops/SP/play//view/Main/ConfigurationVariables HTTP/1.1" 200 58292 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:54:37 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.1" 200 4665 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:55:03 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.1" 200 4232 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:55:17 -0800] "GET /ops/SP/play//view/Main/VerifingGatway HTTP/1.1" 200 4750 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:55:40 -0800] "GET /ops/SP/play//view/Main/KevinWGagel HTTP/1.1" 200 4901 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:55:49 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.1" 200 4534 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:56:10 -0800] "GET /ops/SP/play//view/Main/SideBar HTTP/1.1" 200 3972 +ts05-ip44.hevanet.com - - [10/Mar/2004:08:56:13 -0800] "GET /ops/SP/play//view/Main/DCCGraphs HTTP/1.1" 200 5402 +lj1048.passgo.com - - [10/Mar/2004:09:05:59 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1145.passgo.com - - [10/Mar/2004:09:05:59 -0800] "GET /ops/SP/play//oops/TWiki/MoveTopic HTTP/1.0" 200 209 +cacher2-ext.wise.edt.ericsson.se - - [10/Mar/2004:09:41:56 -0800] "GET /razor.jsp HTTP/1.0" 200 2869 +adsl-64-173-42-65.dsl.snfc21.pacbell.net - - [10/Mar/2004:10:37:53 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +ic8234.upco.es - - [10/Mar/2004:10:38:04 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +ic8234.upco.es - - [10/Mar/2004:10:38:05 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +ic8234.upco.es - - [10/Mar/2004:10:38:23 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +ic8234.upco.es - - [10/Mar/2004:10:38:27 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.1" 200 3629 +ns.mou.cz - - [10/Mar/2004:10:59:06 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:12:51 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +lj1117.passgo.com - - [10/Mar/2004:11:13:21 -0800] "GET /ops/SP/play//view/Know/WebStatistics HTTP/1.0" 200 6394 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:18:59 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 2082 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:19:00 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:19:00 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:19:00 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:19:32 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 19597 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:41:25 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 2082 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:41:25 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:41:25 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:41:25 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:41:52 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 19597 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:43:26 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:44:13 -0800] "GET /mailman/admin/ppwc/members HTTP/1.1" 200 15271 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:44:27 -0800] "GET /mailman/admin/ppwc/members?letter=n HTTP/1.1" 200 15131 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:44:44 -0800] "GET /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 24507 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:45:22 -0800] "GET /mailman/admin/ppwc/passwords HTTP/1.1" 200 6217 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:45:51 -0800] "GET /mailman/admin/ppwc/gateway HTTP/1.1" 200 0 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:45:51 -0800] "GET /mailman/admin/ppwc/gateway HTTP/1.1" 200 8692 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:46:42 -0800] "GET /mailman/admin/ppwc/general HTTP/1.1" 200 19597 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:47:37 -0800] "GET /mailman/admin/ppwc/?VARHELP=general/owner HTTP/1.1" 200 3505 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:49:57 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 2082 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:49:57 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:49:57 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:49:57 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:50:28 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:50:35 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:52:14 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +h24-71-236-129.ca.clawio.org - - [10/Mar/2004:11:52:42 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +10.0.0.176 - - [10/Mar/2004:12:02:38 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:43 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +10.0.0.176 - - [10/Mar/2004:12:02:43 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:45 -0800] "GET /mailman HTTP/1.1" 302 301 +10.0.0.176 - - [10/Mar/2004:12:02:46 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +10.0.0.176 - - [10/Mar/2004:12:02:46 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:46 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:46 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:50 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +10.0.0.176 - - [10/Mar/2004:12:02:50 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:50 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:50 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:52 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 2082 +10.0.0.176 - - [10/Mar/2004:12:02:52 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:52 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:52 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:02:59 -0800] "POST /mailman/admin/ppwc HTTP/1.1" 200 19597 +10.0.0.176 - - [10/Mar/2004:12:03:00 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:00 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:00 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:03 -0800] "GET /mailman/admin/ppwc/members HTTP/1.1" 200 15271 +10.0.0.176 - - [10/Mar/2004:12:03:04 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:04 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:04 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:08 -0800] "GET /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 24507 +10.0.0.176 - - [10/Mar/2004:12:03:08 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:08 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:08 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:45 -0800] "GET /mailman/options/ppwc/ppwctwentynine--at--shaw.com HTTP/1.1" 200 14296 +10.0.0.176 - - [10/Mar/2004:12:03:45 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:45 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:03:45 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:06 -0800] "POST /mailman/options/ppwc/ppwctwentynine@shaw.com HTTP/1.1" 200 14579 +10.0.0.176 - - [10/Mar/2004:12:05:06 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:06 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:06 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:22 -0800] "GET /mailman/admin/ppwc HTTP/1.1" 200 19597 +10.0.0.176 - - [10/Mar/2004:12:05:22 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:22 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:22 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:38 -0800] "GET /mailman/admin/ppwc/members HTTP/1.1" 200 15271 +10.0.0.176 - - [10/Mar/2004:12:05:38 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:38 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:38 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:40 -0800] "GET /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 24525 +10.0.0.176 - - [10/Mar/2004:12:05:40 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:40 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:40 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:54 -0800] "POST /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 23169 +10.0.0.176 - - [10/Mar/2004:12:05:54 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:54 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:54 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:58 -0800] "GET /mailman/admin/ppwc/general HTTP/1.1" 200 19597 +10.0.0.176 - - [10/Mar/2004:12:05:58 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:58 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:05:58 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:07 -0800] "GET /mailman/admin/ppwc/members HTTP/1.1" 200 15271 +10.0.0.176 - - [10/Mar/2004:12:06:07 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:07 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:07 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:09 -0800] "GET /mailman/admin/ppwc/members/add HTTP/1.1" 200 6681 +10.0.0.176 - - [10/Mar/2004:12:06:09 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:09 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:06:09 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:07 -0800] "POST /mailman/admin/ppwc/members/add HTTP/1.1" 200 6762 +10.0.0.176 - - [10/Mar/2004:12:07:07 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:07 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:08 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:12 -0800] "GET /mailman/admin/ppwc/members/list HTTP/1.1" 200 15271 +10.0.0.176 - - [10/Mar/2004:12:07:12 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:12 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:13 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:14 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:14 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:14 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:14 -0800] "GET /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 24585 +10.0.0.176 - - [10/Mar/2004:12:07:25 -0800] "POST /mailman/admin/ppwc/members?letter=p HTTP/1.1" 200 24577 +10.0.0.176 - - [10/Mar/2004:12:07:25 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:25 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:07:25 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:16:59 -0800] "GET /mailman/admin/ppwc/logout HTTP/1.1" 200 2103 +10.0.0.176 - - [10/Mar/2004:12:16:59 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:16:59 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:16:59 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +142.27.64.35 - - [10/Mar/2004:12:19:02 -0800] "GET / HTTP/1.1" 304 - +142.27.64.35 - - [10/Mar/2004:12:19:05 -0800] "GET /mailman HTTP/1.1" 302 301 +142.27.64.35 - - [10/Mar/2004:12:19:05 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +142.27.64.35 - - [10/Mar/2004:12:19:06 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +142.27.64.35 - - [10/Mar/2004:12:19:06 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +142.27.64.35 - - [10/Mar/2004:12:19:06 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +142.27.64.35 - - [10/Mar/2004:12:19:08 -0800] "GET /mailman/listinfo/ppwc HTTP/1.1" 200 6271 +lj1216.passgo.com - - [10/Mar/2004:12:22:32 -0800] "GET /ops/SP/play//oops/TWiki/WikiTopic HTTP/1.0" 200 209 +10.0.0.176 - - [10/Mar/2004:12:25:25 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:12:25:28 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 8663 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6392 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7133 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 9449 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6895 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9403 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +10.0.0.176 - - [10/Mar/2004:12:25:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +c-411472d5.04-138-73746f22.cust.bredbandsbolaget.se - - [10/Mar/2004:13:13:23 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +3_343_lt_someone - - [10/Mar/2004:13:15:44 -0800] "GET / HTTP/1.1" 200 3169 +3_343_lt_someone - - [10/Mar/2004:13:15:53 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7142 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 5882 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6485 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8673 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6895 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9403 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +3_343_lt_someone - - [10/Mar/2004:13:15:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +watchguard.cgmatane.qc.ca - - [10/Mar/2004:13:41:37 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +watchguard.cgmatane.qc.ca - - [10/Mar/2004:13:42:23 -0800] "GET /RBL.jsp HTTP/1.1" 200 4114 +ppp2.p33.is.com.ua - - [10/Mar/2004:14:20:51 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +ppp2.p33.is.com.ua - - [10/Mar/2004:14:21:36 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +ppp2.p33.is.com.ua - - [10/Mar/2004:14:22:13 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +10.0.0.176 - - [10/Mar/2004:15:06:20 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [10/Mar/2004:15:06:24 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [10/Mar/2004:15:06:24 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 5871 +10.0.0.176 - - [10/Mar/2004:15:06:24 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6484 +10.0.0.176 - - [10/Mar/2004:15:06:24 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 7014 +10.0.0.176 - - [10/Mar/2004:15:06:24 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8821 +10.0.0.176 - - [10/Mar/2004:15:06:25 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9306 +10.0.0.176 - - [10/Mar/2004:15:06:25 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6937 +10.0.0.176 - - [10/Mar/2004:15:06:25 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +10.0.0.176 - - [10/Mar/2004:15:06:25 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +lj1024.passgo.com - - [10/Mar/2004:15:10:10 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1028.passgo.com - - [10/Mar/2004:15:10:13 -0800] "GET /ops/SP/play//oops/Main/T HTTP/1.0" 200 209 +lj1145.passgo.com - - [10/Mar/2004:15:49:55 -0800] "GET /ops/SP/play//oops/TWiki/NicholasLee HTTP/1.0" 200 209 +h24-68-45-227.gv.shawcable.net - - [10/Mar/2004:16:29:30 -0800] "GET /pipermail/cnc_notice/2004-February.txt HTTP/1.1" 200 6712 +64.246.94.141 - - [10/Mar/2004:16:31:19 -0800] "HEAD /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 0 +pntn02m05-129.bctel.ca - - [10/Mar/2004:16:33:04 -0800] "GET /pipermail/cncce/2004-January/000001.jsp HTTP/1.1" 200 3095 +calcite.rhyolite.com - - [10/Mar/2004:16:47:44 -0800] "GET /clients.jsp HTTP/1.1" 200 18971 +h24-68-45-227.gv.shawcable.net - - [10/Mar/2004:16:52:44 -0800] "GET /pipermail/cnc_notice/2003-December.txt HTTP/1.1" 200 6570 +h24-68-45-227.gv.shawcable.net - - [10/Mar/2004:16:54:36 -0800] "GET /pipermail/cnc_notice/2003-December/000002.jsp HTTP/1.1" 200 7074 +lj1117.passgo.com - - [10/Mar/2004:18:13:54 -0800] "GET /ops/SP/play//view/Main/VishaalGolam HTTP/1.0" 200 4577 +lj1073.passgo.com - - [10/Mar/2004:18:17:24 -0800] "GET /ops/SP/play//oops/TWiki/Wik HTTP/1.0" 200 209 +lj1024.passgo.com - - [10/Mar/2004:19:55:54 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1000.passgo.com - - [10/Mar/2004:19:55:56 -0800] "GET /ops/SP/play//view/Know/WebHome HTTP/1.0" 200 7529 +dialup-5-81.tulane.edu - - [10/Mar/2004:20:22:41 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +dialup-5-81.tulane.edu - - [10/Mar/2004:20:22:42 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +dialup-5-81.tulane.edu - - [10/Mar/2004:20:23:11 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +dialup-5-81.tulane.edu - - [10/Mar/2004:20:23:41 -0800] "GET /ops/SP/play//view/Main/TWikiGroups HTTP/1.1" 200 4816 +dialup-5-81.tulane.edu - - [10/Mar/2004:20:23:52 -0800] "GET /ops/SP/play//view/Main/TWikiAdminGroup HTTP/1.1" 200 4175 +lj1145.passgo.com - - [10/Mar/2004:21:56:34 -0800] "GET /ops/SP/play//oops/Main/WebStatistics HTTP/1.0" 200 209 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:58:46 -0800] "GET / HTTP/1.1" 200 3169 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:58:46 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:16 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:17 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 5664 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:17 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6403 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8837 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6980 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9241 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6970 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:21:59:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:03 -0800] "GET /ststats/index.jsp HTTP/1.1" 200 2955 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:04 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3093 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2255 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3419 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2381 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1658 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2657 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 2008 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1598 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2223 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1924 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:22:00:05 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1550 +lj1220.passgo.com - - [10/Mar/2004:22:16:58 -0800] "GET /ops/SP/play//oops/TWiki/SvenDowideit HTTP/1.0" 200 209 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:28 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:30 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 5805 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:30 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6445 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:30 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8809 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6882 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9241 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6970 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6619 +h24-70-69-74.ca.clawio.org - - [10/Mar/2004:23:08:31 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5517 +lj1024.passgo.com - - [11/Mar/2004:00:07:57 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1117.passgo.com - - [11/Mar/2004:00:07:58 -0800] "GET /ops/SP/play//oops/Know/WebStatistics HTTP/1.0" 200 209 +lj1120.passgo.com - - [11/Mar/2004:00:42:01 -0800] "GET /ops/SP/play//view/Main/DCCAndPostFix HTTP/1.0" 200 5234 +ns3.vonroll.ch - - [11/Mar/2004:00:43:57 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +ns3.vonroll.ch - - [11/Mar/2004:00:43:59 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.0" 200 2877 +ns3.vonroll.ch - - [11/Mar/2004:00:44:08 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.0" 200 4646 +lj1145.passgo.com - - [11/Mar/2004:01:39:53 -0800] "GET /ops/SP/play//view/Main/SimonMudd HTTP/1.0" 200 4612 +1513.cps.virtua.com.br - - [11/Mar/2004:02:27:39 -0800] "GET /pipermail/cipg/2003-november.txt HTTP/1.1" 404 309 +194.151.73.43 - - [11/Mar/2004:03:35:49 -0800] "GET /ie.htm HTTP/1.0" 200 3518 +194.151.73.43 - - [11/Mar/2004:03:35:57 -0800] "GET /images/image004.jpg HTTP/1.0" 200 10936 +194.151.73.43 - - [11/Mar/2004:03:35:57 -0800] "GET /images/image005.jpg HTTP/1.0" 200 21125 +194.151.73.43 - - [11/Mar/2004:03:35:58 -0800] "GET /images/msgops.JPG HTTP/1.0" 200 7939 +spica.ukc.ac.uk - - [11/Mar/2004:03:50:09 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +spica.ukc.ac.uk - - [11/Mar/2004:03:50:09 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +ogw.netinfo.nl - - [11/Mar/2004:06:11:19 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +ogw.netinfo.nl - - [11/Mar/2004:06:11:21 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +ogw.netinfo.nl - - [11/Mar/2004:06:11:38 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.1" 200 4016 +ogw.netinfo.nl - - [11/Mar/2004:06:11:39 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:06:11:46 -0800] "GET /ops/SP/play//view/Main/PostfixCmd HTTP/1.1" 200 4173 +ogw.netinfo.nl - - [11/Mar/2004:06:11:47 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:06:12:41 -0800] "GET /ops/SP/play//view/Main/PostQueue HTTP/1.1" 200 4280 +ogw.netinfo.nl - - [11/Mar/2004:06:12:43 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:06:13:07 -0800] "GET /ops/SP/play//view/Main/PostSuper HTTP/1.1" 200 3629 +ogw.netinfo.nl - - [11/Mar/2004:06:13:08 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:06:14:03 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.1" 200 4665 +ogw.netinfo.nl - - [11/Mar/2004:06:14:04 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:06:16:40 -0800] "GET /ops/SP/play//view/Main/RelayGateway HTTP/1.1" 200 4232 +ogw.netinfo.nl - - [11/Mar/2004:06:17:06 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.1" 200 4534 +ogw.netinfo.nl - - [11/Mar/2004:06:17:11 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +lj1024.passgo.com - - [11/Mar/2004:06:27:31 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1153.passgo.com - - [11/Mar/2004:06:27:36 -0800] "GET /ops/SP/play//oops/Sandbox/WebStatistics HTTP/1.0" 200 209 +208-186-146-13.nrp3.brv.mn.frontiernet.net - - [11/Mar/2004:06:48:05 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +208-186-146-13.nrp3.brv.mn.frontiernet.net - - [11/Mar/2004:06:48:05 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +ladybug.cns.vt.edu - - [11/Mar/2004:07:15:10 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +ladybug.cns.vt.edu - - [11/Mar/2004:07:15:11 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +ladybug.cns.vt.edu - - [11/Mar/2004:07:19:57 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +ladybug.cns.vt.edu - - [11/Mar/2004:07:20:05 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +ladybug.cns.vt.edu - - [11/Mar/2004:07:20:09 -0800] "GET /ops/SP/play//view/Main/SpamAssassinTaggingOnly HTTP/1.1" 200 5691 +osdlab.eic.nctu.edu.tw - - [11/Mar/2004:07:39:30 -0800] "GET /M83A HTTP/1.0" 404 269 +208.247.148.12 - - [11/Mar/2004:08:14:18 -0800] "GET /mailman/listinfo/ppwc HTTP/1.0" 200 6252 +208.247.148.12 - - [11/Mar/2004:08:14:18 -0800] "GET /icons/mailman.jpg HTTP/1.0" 200 2022 +208.247.148.12 - - [11/Mar/2004:08:14:18 -0800] "GET /icons/PythonPowered.png HTTP/1.0" 200 945 +208.247.148.12 - - [11/Mar/2004:08:14:18 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.0" 200 3049 +ogw.netinfo.nl - - [11/Mar/2004:08:45:41 -0800] "GET /ops/SP/play//view/Main/SpamAssassinAndPostFix HTTP/1.1" 200 4034 +ogw.netinfo.nl - - [11/Mar/2004:08:45:42 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +ogw.netinfo.nl - - [11/Mar/2004:08:45:49 -0800] "GET /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 5543 +ogw.netinfo.nl - - [11/Mar/2004:08:45:54 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +0x503e4fce.virnxx2.adsl-dhcp.tele.dk - - [11/Mar/2004:10:55:40 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +0x503e4fce.virnxx2.adsl-dhcp.tele.dk - - [11/Mar/2004:10:58:16 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +0x503e4fce.virnxx2.adsl-dhcp.tele.dk - - [11/Mar/2004:10:58:27 -0800] "GET /razor.jsp HTTP/1.1" 304 - +64-93-34-186.client.dsl.net - - [11/Mar/2004:11:12:40 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +d207-6-50-215.bchsia.telus.net - - [11/Mar/2004:11:33:35 -0800] "GET /pipermail/cncce/2004-January/000001.jsp HTTP/1.1" 200 3095 +10.0.0.176 - - [11/Mar/2004:11:49:51 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [11/Mar/2004:11:49:53 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 5622 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6357 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8728 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6791 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9561 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 7087 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6427 +10.0.0.176 - - [11/Mar/2004:11:49:54 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5598 +1-729.tnr.on.ca - - [11/Mar/2004:11:54:59 -0800] "GET / HTTP/1.1" 200 3169 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:22 -0800] "GET /mailman HTTP/1.1" 302 301 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:22 -0800] "GET /mailman/listinfo HTTP/1.1" 200 6893 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:22 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:23 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:23 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +1-729.tnr.on.ca - - [11/Mar/2004:11:55:26 -0800] "GET /mailman/listinfo/administration HTTP/1.1" 200 6459 +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:28:50 -0800] "GET /mailman/admindb/ppwc HTTP/1.1" 200 2072 +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:28:50 -0800] "GET /icons/mailman.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:28:51 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:28:51 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 304 - +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:29:03 -0800] "POST /mailman/admindb/ppwc HTTP/1.1" 200 3407 +h24-71-236-129.ca.clawio.org - - [11/Mar/2004:12:29:27 -0800] "POST /mailman/admindb/ppwc HTTP/1.1" 200 1134 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:56:35 -0800] "GET /robots.txt HTTP/1.0" 200 68 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:56:58 -0800] "GET /ops/SP/play//view/TWiki/WebStatistics HTTP/1.0" 200 8193 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:57:18 -0800] "GET /ops/SP/play//view/Main/TWikiGuest HTTP/1.0" 200 4430 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:57:24 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=1.25 HTTP/1.0" 200 9812 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:57:45 -0800] "GET /ops/SP/play//view/Main/WebNotify?rev=r1.6 HTTP/1.0" 200 4300 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:58:03 -0800] "GET /ops/SP/play//rdiff/TWiki/ManagingTopics?rev1=1.16&rev2=1.15 HTTP/1.0" 200 7912 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:58:37 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=r1.8 HTTP/1.0" 200 8986 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:58:50 -0800] "GET /ops/SP/play//edit/Main/Max_idle?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:59:07 -0800] "GET /ops/SP/play//view/Main/WebChanges HTTP/1.0" 200 40430 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:59:33 -0800] "GET /ops/SP/play//search/TWiki/SearchResult?scope=text®ex=on&search=Appendix%20*File%20*System%5B%5EA-Za-z%5D HTTP/1.0" 200 5794 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:12:59:52 -0800] "GET /ops/SP/play//oops/TWiki/AppendixFileSystem?template=oopsmore¶m1=1.12¶m2=1.12 HTTP/1.0" 200 11355 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:00:12 -0800] "GET /ops/SP/play//view/TWiki/WebTopicViewTemplate HTTP/1.0" 200 5420 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:00:47 -0800] "GET /ops/SP/play//rdiff/Main/WebHome HTTP/1.0" 200 69197 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:00:57 -0800] "GET /ops/SP/play//view/TWiki/WebPreferences?rev=r1.9 HTTP/1.0" 200 7875 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:01:21 -0800] "GET /ops/SP/play//rdiff/Main/ConfigurationVariables?rev1=1.2&rev2=1.1 HTTP/1.0" 200 59549 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:01:37 -0800] "GET /ops/SP/play//view/Main/AndreaSterbini HTTP/1.0" 200 3891 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:01:58 -0800] "GET /ops/SP/play//rdiff/Main/AndreaSterbini HTTP/1.0" 200 5567 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:02:22 -0800] "GET /ops/SP/play//rdiff/TWiki/WebNotify HTTP/1.0" 200 11733 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:02:42 -0800] "GET /ops/SP/play//rdiff/Main/WebHome?rev1=1.28&rev2=1.27 HTTP/1.0" 200 3577 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:03:06 -0800] "GET /ops/SP/play//view/Main/WebHome?skin=print HTTP/1.0" 200 8347 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:03:23 -0800] "GET /ops/SP/play//search/Main/SearchResult?search=%5C.*&scope=topic&order=modified&reverse=on®ex=on&nosearch=on HTTP/1.0" 200 43816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:03:48 -0800] "GET /ops/SP/play//view/TWiki/FormattedSearch HTTP/1.0" 200 20420 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:04:09 -0800] "GET /ops/SP/play//oops/Main/WebHome?template=oopsmore¶m1=1.28¶m2=1.8 HTTP/1.0" 200 7410 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:04:30 -0800] "GET /ops/SP/play//edit/TWiki/TextFormattingFAQ?t=1075982736 HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:04:52 -0800] "GET /ops/SP/play//edit/Main/Allow_untrusted_routing?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:05:13 -0800] "GET /ops/SP/play//edit/Main/Smtp_data_init_timeout?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:05:33 -0800] "GET /ops/SP/play//view/TWiki/AppendixFileSystem?rev=1.10 HTTP/1.0" 200 34910 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:05:54 -0800] "GET /ops/SP/play//view/Main/AndreaSterbini?rev=r1.1 HTTP/1.0" 200 3732 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:06:17 -0800] "GET /ops/SP/play//view/Know/WebNotify HTTP/1.0" 200 4472 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:06:39 -0800] "GET /ops/SP/play//rdiff/Main/PeterThoeny HTTP/1.0" 200 18859 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:07:02 -0800] "GET /ops/SP/play//view/Main/WebHome?skin=print&rev=1.25 HTTP/1.0" 200 7762 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:07:20 -0800] "GET /ops/SP/play//edit/Main/Relayhost?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:07:40 -0800] "GET /ops/SP/play//edit/Main/Unknown_virtual_mailbox_reject_code?topicparent=Main.ConfigurationVariables HTTP/1.0" 401 12816 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:08:03 -0800] "GET /ops/SP/play//view/TWiki/WebPreferences HTTP/1.0" 200 9109 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:08:44 -0800] "GET /ops/SP/play//view/Main/DCC HTTP/1.0" 200 4377 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:09:04 -0800] "GET /ops/SP/play//view/Know/WebHome HTTP/1.0" 200 7529 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:09:21 -0800] "GET /ops/SP/play//view/Main/WebNotify HTTP/1.0" 200 4449 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:09:24 -0800] "GET /ops/SP/play//oops/Main/WebHome?template=oopsmore¶m1=1.28¶m2=1.28 HTTP/1.0" 200 7411 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:09:52 -0800] "GET /ops/SP/play//view/Main/PostfixCommands HTTP/1.0" 200 4004 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:10:11 -0800] "GET /ops/SP/play//view/TWiki/WebHome HTTP/1.0" 200 15147 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:10:27 -0800] "GET /ops/SP/play//view/Main/RBLsHowTo HTTP/1.0" 200 4646 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:10:52 -0800] "GET /ops/SP/play//view/Main/WebTopicList HTTP/1.0" 200 7461 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:11:09 -0800] "GET /ops/SP/play//view/Main/WebHome?rev=1.27 HTTP/1.0" 200 10313 +cr020r01-3.uah.goweb.net - - [11/Mar/2004:13:11:41 -0800] "GET /ops/SP/play//view/Main/ConfigurationVariables HTTP/1.0" 200 58169 +4.37.97.186 - - [11/Mar/2004:13:12:54 -0800] "GET /pipermail/webber/2004-January/000000.jsp HTTP/1.1" 200 2446 +12.22.207.235 - - [11/Mar/2004:13:18:15 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +archserve.id.ucsb.edu - - [11/Mar/2004:13:22:32 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +archserve.id.ucsb.edu - - [11/Mar/2004:13:22:32 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +2-110.tnr.on.ca - - [11/Mar/2004:13:24:03 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +2-110.tnr.on.ca - - [11/Mar/2004:13:24:04 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +2-110.tnr.on.ca - - [11/Mar/2004:13:24:04 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +2-110.tnr.on.ca - - [11/Mar/2004:13:24:04 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +2-110.tnr.on.ca - - [11/Mar/2004:13:26:38 -0800] "GET /images/image005.jpg HTTP/1.1" 304 - +2-110.tnr.on.ca - - [11/Mar/2004:13:26:38 -0800] "GET /images/image004.jpg HTTP/1.1" 304 - +2-110.tnr.on.ca - - [11/Mar/2004:13:26:38 -0800] "GET /images/msgops.JPG HTTP/1.1" 304 - +lj1024.passgo.com - - [11/Mar/2004:13:27:05 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1212.passgo.com - - [11/Mar/2004:13:27:05 -0800] "GET / HTTP/1.0" 200 3169 +2-110.tnr.on.ca - - [11/Mar/2004:14:14:44 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +2-110.tnr.on.ca - - [11/Mar/2004:14:14:47 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +2-110.tnr.on.ca - - [11/Mar/2004:14:14:47 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +2-110.tnr.on.ca - - [11/Mar/2004:14:14:50 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +favr.go.de - - [11/Mar/2004:14:22:08 -0800] "GET /robots.txt HTTP/1.0" 200 68 +favr.go.de - - [11/Mar/2004:14:22:09 -0800] "GET /ops/SP/play//view/Main/WebSearch HTTP/1.0" 200 9263 +favr.go.de - - [11/Mar/2004:14:26:26 -0800] "GET /ops/SP/play//view/Sandbox/WebHome HTTP/1.0" 200 8605 +favr.go.de - - [11/Mar/2004:14:28:53 -0800] "GET /ops/SP/play//view/Sandbox/WebChanges HTTP/1.0" 200 9622 +favr.go.de - - [11/Mar/2004:14:29:44 -0800] "GET /ops/SP/play//view/Sandbox/WebPreferences HTTP/1.0" 200 8380 +favr.go.de - - [11/Mar/2004:14:29:52 -0800] "GET /ops/SP/play//view/Main/WebStatistics HTTP/1.0" 200 8331 +favr.go.de - - [11/Mar/2004:14:30:51 -0800] "GET /ops/SP/play//view/Main/WebTopicList HTTP/1.0" 200 7461 +favr.go.de - - [11/Mar/2004:14:31:43 -0800] "GET /ops/SP/play//view/Main/WebPreferences HTTP/1.0" 200 8793 +lj1008.passgo.com - - [11/Mar/2004:14:31:48 -0800] "GET /ops/SP/play//oops/TWiki/WikiWikiClones HTTP/1.0" 200 209 +favr.go.de - - [11/Mar/2004:14:33:01 -0800] "GET /ops/SP/play//view/Main/WebNotify HTTP/1.0" 200 4449 +64-249-27-114.client.dsl.net - - [11/Mar/2004:14:53:12 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +pd9eb1396.dip.t-dialin.net - - [11/Mar/2004:15:17:08 -0800] "GET /AmavisNew.jsp HTTP/1.1" 200 2300 +10.0.0.176 - - [11/Mar/2004:15:51:49 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [11/Mar/2004:15:52:07 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +10.0.0.176 - - [11/Mar/2004:15:52:07 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +10.0.0.176 - - [11/Mar/2004:15:52:12 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +10.0.0.176 - - [11/Mar/2004:15:52:12 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +10.0.0.176 - - [11/Mar/2004:15:52:18 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 6329 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8771 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6340 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6846 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9523 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 6996 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6427 +10.0.0.176 - - [11/Mar/2004:15:52:19 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5598 +10.0.0.176 - - [11/Mar/2004:15:52:37 -0800] "GET /ststats/index.jsp HTTP/1.1" 304 - +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3241 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3327 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2434 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1676 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 2029 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1604 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2640 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2251 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1899 +10.0.0.176 - - [11/Mar/2004:15:52:38 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1556 +10.0.0.176 - - [11/Mar/2004:15:52:39 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2243 +lj1105.passgo.com - - [11/Mar/2004:16:02:37 -0800] "GET /ops/SP/play//oops/TWiki/1000 HTTP/1.0" 200 209 +wc01.piwa.pow.fr - - [11/Mar/2004:16:12:59 -0800] "GET /ie.htm HTTP/1.1" 200 3518 +wc01.piwa.pow.fr - - [11/Mar/2004:16:13:02 -0800] "GET /images/image005.jpg HTTP/1.1" 200 21125 +wc01.piwa.pow.fr - - [11/Mar/2004:16:13:02 -0800] "GET /images/msgops.JPG HTTP/1.1" 200 7939 +wc03.mtnk.rnc.net.cable.rogers.com - - [11/Mar/2004:16:13:03 -0800] "GET /images/image004.jpg HTTP/1.1" 200 10936 +206-15-133-154.dialup.ziplink.net - - [11/Mar/2004:16:33:23 -0800] "HEAD /ops/SP/play//view/Main/SpamAssassinDeleting HTTP/1.1" 200 0 +lj1024.passgo.com - - [11/Mar/2004:18:11:39 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1008.passgo.com - - [11/Mar/2004:18:11:40 -0800] "GET /ops/SP/play//oops/Main/Smtpd_recipient_limit HTTP/1.0" 200 209 +ipcorp-c8b07af1.terraempresas.com.br - - [11/Mar/2004:18:31:35 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 +66-194-6-79.gen.twtelecom.net - - [11/Mar/2004:18:57:52 -0800] "GET / HTTP/1.1" 200 3169 +lj1223.passgo.com - - [11/Mar/2004:20:12:24 -0800] "GET /ops/SP/play//view/Main/MikeMannix HTTP/1.0" 200 3674 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:32 -0800] "GET /ststats/ HTTP/1.1" 200 2955 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:37 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 3091 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:37 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2230 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:37 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2388 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:37 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3440 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1659 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2662 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 2064 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1624 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2243 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1879 +216-160-111-121.tukw.qwest.net - - [11/Mar/2004:20:49:38 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1575 +lj1073.passgo.com - - [11/Mar/2004:20:59:05 -0800] "GET /ops/SP/play//oops/TWiki/TWikiPlannedFeatures HTTP/1.0" 200 209 +mmscrm07-2.uah.goweb.net - - [11/Mar/2004:23:56:31 -0800] "GET /robots.txt HTTP/1.0" 200 68 +66-194-6-71.gen.twtelecom.net - - [12/Mar/2004:01:30:44 -0800] "GET / HTTP/1.1" 200 3169 +lj1024.passgo.com - - [12/Mar/2004:02:27:29 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1123.passgo.com - - [12/Mar/2004:02:27:32 -0800] "GET /ops/SP/play//view/Sandbox/WebIndex HTTP/1.0" 200 8667 +195.11.231.210 - - [12/Mar/2004:03:32:56 -0800] "GET /mailman/listinfo/webber HTTP/1.0" 200 6032 +80.58.33.42.proxycache.rima-tde.net - - [12/Mar/2004:04:57:20 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.0" 200 10392 +80.58.33.42.proxycache.rima-tde.net - - [12/Mar/2004:04:57:21 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +80.58.33.42.proxycache.rima-tde.net - - [12/Mar/2004:04:57:56 -0800] "GET /ops/SP/play//view/Main/LinksOfUse HTTP/1.1" 200 4534 +200.100.10.5 - - [12/Mar/2004:04:59:21 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +200.100.10.5 - - [12/Mar/2004:04:59:21 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +lj1115.passgo.com - - [12/Mar/2004:05:03:19 -0800] "GET /ops/SP/play//view/Main/TWikiAdminGroup HTTP/1.0" 200 4156 +lj1008.passgo.com - - [12/Mar/2004:05:19:31 -0800] "GET /ops/SP/play//oops/TWiki/Mana HTTP/1.0" 200 209 +71.134.70.5 - - [12/Mar/2004:05:25:20 -0800] "GET /mailman/listinfo/cncce HTTP/1.1" 200 6208 +71.134.70.5 - - [12/Mar/2004:05:25:24 -0800] "GET /icons/mailman.jpg HTTP/1.1" 200 2022 +71.134.70.5 - - [12/Mar/2004:05:25:24 -0800] "GET /icons/PythonPowered.png HTTP/1.1" 200 945 +71.134.70.5 - - [12/Mar/2004:05:25:25 -0800] "GET /icons/gnu-head-tiny.jpg HTTP/1.1" 200 3049 +200.100.10.5 - - [12/Mar/2004:05:44:35 -0800] "GET /ops/SP/play//view/Main/SpamAssassinUsingRazorAndDCC HTTP/1.1" 200 7435 +200.100.10.5 - - [12/Mar/2004:05:44:35 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +200.100.10.5 - - [12/Mar/2004:05:44:50 -0800] "GET /ops/SP/play//view/Main/DCC HTTP/1.1" 200 4396 +200.100.10.5 - - [12/Mar/2004:05:44:51 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 304 - +200.100.10.5 - - [12/Mar/2004:05:51:36 -0800] "GET /favicon.ico HTTP/1.1" 200 1078 +vlp181.vlp.fi - - [12/Mar/2004:08:33:32 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +lj1024.passgo.com - - [12/Mar/2004:09:12:01 -0800] "GET /robots.txt HTTP/1.0" 200 68 +lj1223.passgo.com - - [12/Mar/2004:09:12:02 -0800] "GET /ops/SP/play//oops/Main/Mi HTTP/1.0" 200 209 +10.0.0.176 - - [12/Mar/2004:11:01:26 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [12/Mar/2004:11:01:28 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 6405 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6413 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6952 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8715 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 7001 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9514 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6644 +10.0.0.176 - - [12/Mar/2004:11:01:29 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5554 +fassys.org - - [12/Mar/2004:11:16:36 -0800] "GET /ststats/ HTTP/1.0" 200 2955 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.0" 200 2925 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.0" 200 2347 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.0" 200 3431 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.0" 200 2380 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.0" 200 1658 +fassys.org - - [12/Mar/2004:11:16:55 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.0" 200 2685 +fassys.org - - [12/Mar/2004:11:16:56 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.0" 200 2082 +fassys.org - - [12/Mar/2004:11:16:56 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.0" 200 1637 +fassys.org - - [12/Mar/2004:11:16:56 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.0" 200 2211 +fassys.org - - [12/Mar/2004:11:16:56 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.0" 200 1853 +fassys.org - - [12/Mar/2004:11:16:56 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.0" 200 1572 +67.131.107.5 - - [12/Mar/2004:11:39:14 -0800] "GET / HTTP/1.1" 200 3169 +67.131.107.5 - - [12/Mar/2004:11:39:25 -0800] "GET /ops/SP/play//view/Main/WebHome HTTP/1.1" 200 10419 +67.131.107.5 - - [12/Mar/2004:11:39:31 -0800] "GET /go/bin/test/TWikiLogos/twikiRobot46x50.gif HTTP/1.1" 200 2877 +10.0.0.176 - - [12/Mar/2004:12:23:11 -0800] "GET / HTTP/1.1" 304 - +10.0.0.176 - - [12/Mar/2004:12:23:17 -0800] "GET /forplus/mailgraph2.cgi HTTP/1.1" 200 2987 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0_err.png HTTP/1.1" 200 6324 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1.png HTTP/1.1" 200 8964 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_0.png HTTP/1.1" 200 6225 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2_err.png HTTP/1.1" 200 7001 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_2.png HTTP/1.1" 200 9514 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_1_err.png HTTP/1.1" 200 6949 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3.png HTTP/1.1" 200 6644 +10.0.0.176 - - [12/Mar/2004:12:23:18 -0800] "GET /forplus/mailgraph.cgi/mailgraph_3_err.png HTTP/1.1" 200 5554 +10.0.0.176 - - [12/Mar/2004:12:23:40 -0800] "GET /ststats/index.jsp HTTP/1.1" 304 - +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam.1day.png HTTP/1.1" 200 2964 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam-ratio.1day.png HTTP/1.1" 200 2341 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam-ratio.1week.png HTTP/1.1" 200 2346 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam.1week.png HTTP/1.1" 200 3438 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-hashes.1week.png HTTP/1.1" 200 1670 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam.1month.png HTTP/1.1" 200 2651 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam-ratio.1month.png HTTP/1.1" 200 2023 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-hashes.1month.png HTTP/1.1" 200 1636 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam.1year.png HTTP/1.1" 200 2262 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-spam-ratio.1year.png HTTP/1.1" 200 1906 +10.0.0.176 - - [12/Mar/2004:12:23:41 -0800] "GET /ststats/stats-hashes.1year.png HTTP/1.1" 200 1582 +216.139.185.45 - - [12/Mar/2004:13:04:01 -0800] "GET /mailman/listinfo/webber HTTP/1.1" 200 6051 +pd95f99f2.dip.t-dialin.net - - [12/Mar/2004:13:18:57 -0800] "GET /razor.jsp HTTP/1.1" 200 2869 +d97082.upc-d.chello.nl - - [12/Mar/2004:13:25:45 -0800] "GET /SpamAssassin.jsp HTTP/1.1" 200 7368 diff --git a/saas/.gitignore b/saas/.gitignore new file mode 100644 index 0000000000..3de4cc647e --- /dev/null +++ b/saas/.gitignore @@ -0,0 +1,26 @@ +*.class + +0.* + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* +.resourceCache + +# Packaged files # +*.jar +*.war +*.ear + +# Files generated by integration tests +*.txt +backup-pom.xml +/bin/ +/temp + +#IntelliJ specific +.idea/ +*.iml \ No newline at end of file diff --git a/saas/README.md b/saas/README.md new file mode 100644 index 0000000000..4e0eeea974 --- /dev/null +++ b/saas/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [JIRA REST API Integration](http://www.baeldung.com/jira-rest-api) diff --git a/saas/pom.xml b/saas/pom.xml new file mode 100644 index 0000000000..7c8745910f --- /dev/null +++ b/saas/pom.xml @@ -0,0 +1,84 @@ + + 4.0.0 + com.baeldung + saas + 0.1.0-SNAPSHOT + jar + saas + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + com.atlassian.jira + jira-rest-java-client-core + 4.0.0 + + + com.atlassian.fugue + fugue + 2.6.1 + + + com.google.guava + guava + 19.0 + + + + + + saas + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + java + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + -Xmx300m + -XX:+UseParallelGC + -classpath + + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + + + + + + + + atlassian-public + https://packages.atlassian.com/maven/repository/public + + + + + 3.6.0 + + \ No newline at end of file diff --git a/saas/src/main/java/com/baeldung/saas/jira/MyJiraClient.java b/saas/src/main/java/com/baeldung/saas/jira/MyJiraClient.java new file mode 100644 index 0000000000..ff1de5a6d0 --- /dev/null +++ b/saas/src/main/java/com/baeldung/saas/jira/MyJiraClient.java @@ -0,0 +1,103 @@ +package com.baeldung.saas.jira; + +import com.atlassian.jira.rest.client.api.IssueRestClient; +import com.atlassian.jira.rest.client.api.JiraRestClient; +import com.atlassian.jira.rest.client.api.domain.BasicVotes; +import com.atlassian.jira.rest.client.api.domain.Comment; +import com.atlassian.jira.rest.client.api.domain.Issue; +import com.atlassian.jira.rest.client.api.domain.input.IssueInput; +import com.atlassian.jira.rest.client.api.domain.input.IssueInputBuilder; +import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory; + +import java.io.IOException; +import java.net.URI; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +public class MyJiraClient { + + private String username; + private String password; + private String jiraUrl; + private JiraRestClient restClient; + + private MyJiraClient(String username, String password, String jiraUrl) { + this.username = username; + this.password = password; + this.jiraUrl = jiraUrl; + this.restClient = getJiraRestClient(); + } + + public static void main(String[] args) throws IOException { + + MyJiraClient myJiraClient = new MyJiraClient("user.name", "pass", "http://jira.company.com"); + + final String issueKey = myJiraClient.createIssue("ABCD", 1L, "Issue created from JRJC"); + myJiraClient.updateIssueDescription(issueKey, "This is description from my Jira Client"); + Issue issue = myJiraClient.getIssue(issueKey); + System.out.println(issue.getDescription()); + + myJiraClient.voteForAnIssue(issue); + + System.out.println(myJiraClient.getTotalVotesCount(issueKey)); + + myJiraClient.addComment(issue, "This is comment from my Jira Client"); + + List comments = myJiraClient.getAllComments(issueKey); + comments.forEach(c -> System.out.println(c.getBody())); + + myJiraClient.deleteIssue(issueKey, true); + + myJiraClient.restClient.close(); + } + + private String createIssue(String projectKey, Long issueType, String issueSummary) { + + IssueRestClient issueClient = restClient.getIssueClient(); + + IssueInput newIssue = new IssueInputBuilder(projectKey, issueType, issueSummary).build(); + + return issueClient.createIssue(newIssue).claim().getKey(); + } + + private Issue getIssue(String issueKey) { + return restClient.getIssueClient().getIssue(issueKey).claim(); + } + + private void voteForAnIssue(Issue issue) { + restClient.getIssueClient().vote(issue.getVotesUri()).claim(); + } + + private int getTotalVotesCount(String issueKey) { + BasicVotes votes = getIssue(issueKey).getVotes(); + return votes == null ? 0 : votes.getVotes(); + } + + private void addComment(Issue issue, String commentBody) { + restClient.getIssueClient().addComment(issue.getCommentsUri(), Comment.valueOf(commentBody)); + } + + private List getAllComments(String issueKey) { + return StreamSupport.stream(getIssue(issueKey).getComments().spliterator(), false) + .collect(Collectors.toList()); + } + + private void updateIssueDescription(String issueKey, String newDescription) { + IssueInput input = new IssueInputBuilder().setDescription(newDescription).build(); + restClient.getIssueClient().updateIssue(issueKey, input).claim(); + } + + private void deleteIssue(String issueKey, boolean deleteSubtasks) { + restClient.getIssueClient().deleteIssue(issueKey, deleteSubtasks).claim(); + } + + private JiraRestClient getJiraRestClient() { + return new AsynchronousJiraRestClientFactory() + .createWithBasicHttpAuthentication(getJiraUri(), this.username, this.password); + } + + private URI getJiraUri() { + return URI.create(this.jiraUrl); + } +} diff --git a/spring-5-mvc/pom.xml b/spring-5-mvc/pom.xml index db4ffa9abb..b188ee590a 100644 --- a/spring-5-mvc/pom.xml +++ b/spring-5-mvc/pom.xml @@ -14,7 +14,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.0.M1 + 2.0.0.M3 @@ -66,7 +66,6 @@ com.fasterxml.jackson.module jackson-module-kotlin - 2.8.7 @@ -153,7 +152,7 @@ org.apache.maven.plugins maven-surefire-plugin - true + false **/*IntegrationTest.java @@ -166,14 +165,6 @@ - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - spring-milestones Spring Milestones @@ -184,14 +175,6 @@ - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - spring-milestones Spring Milestones diff --git a/spring-5-mvc/src/test/kotlin/com/baeldung/LiveTest.java b/spring-5-mvc/src/test/kotlin/com/baeldung/LiveTest.java index 1b52f89117..b2f2852dbe 100644 --- a/spring-5-mvc/src/test/kotlin/com/baeldung/LiveTest.java +++ b/spring-5-mvc/src/test/kotlin/com/baeldung/LiveTest.java @@ -14,16 +14,19 @@ public class LiveTest { private static String APP_ROOT = "http://localhost:8081"; - @Test public void givenUser_whenResourceCreatedWithNullName_then400BadRequest() { - final Response response = givenAuth("user", "pass").contentType(MediaType.APPLICATION_JSON.toString()).body(resourceWithNullName()).post(APP_ROOT + "/foos"); + final Response response = givenAuth("user", "pass").contentType(MediaType.APPLICATION_JSON.toString()) + .body(resourceWithNullName()) + .post(APP_ROOT + "/foos"); assertEquals(400, response.getStatusCode()); } - + @Test public void givenUser_whenResourceCreated_then201Created() { - final Response response = givenAuth("user", "pass").contentType(MediaType.APPLICATION_JSON.toString()).body(resourceString()).post(APP_ROOT + "/foos"); + final Response response = givenAuth("user", "pass").contentType(MediaType.APPLICATION_JSON.toString()) + .body(resourceString()) + .post(APP_ROOT + "/foos"); assertEquals(201, response.getStatusCode()); } @@ -32,21 +35,22 @@ public class LiveTest { final Response response = givenAuth("user", "pass").get(APP_ROOT + "/foos"); assertEquals(200, response.getStatusCode()); }*/ - - // private final String resourceWithNullName() { return "{\"name\":null}"; } - + private final String resourceString() { return "{\"name\":\"" + randomAlphabetic(8) + "\"}"; - } + } private final RequestSpecification givenAuth(String username, String password) { - return RestAssured.given().auth().preemptive().basic(username, password); + return RestAssured.given() + .auth() + .preemptive() + .basic(username, password); } } \ No newline at end of file diff --git a/spring-5/README.md b/spring-5/README.md index 4ce0fd4c79..1b65d01811 100644 --- a/spring-5/README.md +++ b/spring-5/README.md @@ -9,3 +9,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Introduction to the Functional Web Framework in Spring 5](http://www.baeldung.com/spring-5-functional-web) - [Exploring the Spring 5 MVC URL Matching Improvements](http://www.baeldung.com/spring-5-mvc-url-matching) - [Spring 5 WebClient](http://www.baeldung.com/spring-5-webclient) +- [Spring 5 Functional Bean Registration](http://www.baeldung.com/spring-5-functional-beans) +- [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](http://www.baeldung.com/spring-5-junit-config) diff --git a/spring-5/pom.xml b/spring-5/pom.xml index c2c565aef6..7e30179f07 100644 --- a/spring-5/pom.xml +++ b/spring-5/pom.xml @@ -1,188 +1,204 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - com.baeldung - spring-5 - 0.0.1-SNAPSHOT - jar + com.baeldung + spring-5 + 0.0.1-SNAPSHOT + jar - spring-5 - spring 5 sample project about new features + spring-5 + spring 5 sample project about new features - - org.springframework.boot - spring-boot-starter-parent - 2.0.0.M1 - - + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.M6 + + - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-validation - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-webflux - - - org.projectreactor - reactor-spring - 1.0.1.RELEASE - + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-webflux + + + org.projectreactor + reactor-spring + ${reactor-spring.version} + + + javax.json.bind + javax.json.bind-api + ${jsonb-api.version} + + + + + + + + + + + + + + + org.apache.geronimo.specs + geronimo-json_1.1_spec + ${geronimo-json_1.1_spec.version} + + + org.apache.johnzon + johnzon-jsonb + ${johnzon.version} + + + + org.apache.commons + commons-lang3 + - - - org.apache.commons - commons-lang3 - + - + + org.springframework.boot + spring-boot-devtools + runtime + + + com.h2database + h2 + runtime + - - org.springframework.boot - spring-boot-devtools - runtime - - - com.h2database - h2 - runtime - + + org.springframework + spring-test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + - - org.springframework - spring-test - - - org.springframework.boot - spring-boot-starter-test - test - + + org.apache.commons + commons-collections4 + 4.1 + test + - - org.junit.jupiter - junit-jupiter-api - ${junit.jupiter.version} - - - org.junit.jupiter - junit-jupiter-engine - ${junit.jupiter.version} - test - - - org.junit.platform - junit-platform-surefire-provider - ${junit.platform.version} - test - - - org.junit.platform - junit-platform-runner - ${junit.platform.version} - test - + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + - + - - - - org.springframework.boot - spring-boot-maven-plugin - - com.baeldung.Spring5Application - JAR - - + + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.Spring5Application + JAR + + - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*LiveTest.java - - - + + org.apache.maven.plugins + maven-surefire-plugin + + 3 + true + methods + true + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - methods - true - - + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - UTF-8 - UTF-8 - 1.8 - 1.0.0-M4 - 5.0.0-M4 - 2.20 - 5.0.0.RC2 - + + UTF-8 + UTF-8 + 1.8 + 1.0.0 + 5.0.0 + 2.20 + 5.0.1.RELEASE + 1.0.1.RELEASE + 1.1.3 + 1.0 + 1.0 + diff --git a/spring-5/src/main/java/com/baeldung/Spring5Application.java b/spring-5/src/main/java/com/baeldung/Spring5Application.java index aaff1797ff..f321871646 100644 --- a/spring-5/src/main/java/com/baeldung/Spring5Application.java +++ b/spring-5/src/main/java/com/baeldung/Spring5Application.java @@ -5,7 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication -@ComponentScan(basePackages = {"com.baeldung.web"}) +@ComponentScan(basePackages = { "com.baeldung.web" }) public class Spring5Application { public static void main(String[] args) { diff --git a/spring-5/src/main/java/com/baeldung/SpringSecurity5Application.java b/spring-5/src/main/java/com/baeldung/SpringSecurity5Application.java new file mode 100644 index 0000000000..02c91a1879 --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/SpringSecurity5Application.java @@ -0,0 +1,34 @@ +package com.baeldung; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; +import org.springframework.web.reactive.config.EnableWebFlux; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; +import reactor.ipc.netty.NettyContext; +import reactor.ipc.netty.http.server.HttpServer; + +@ComponentScan(basePackages = {"com.baeldung.security"}) +@EnableWebFlux +public class SpringSecurity5Application { + + public static void main(String[] args) { + try (AnnotationConfigApplicationContext context = + new AnnotationConfigApplicationContext(SpringSecurity5Application.class)) { + context.getBean(NettyContext.class).onClose().block(); + } + } + + @Bean + public NettyContext nettyContext(ApplicationContext context) { + HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context) + .build(); + ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler); + HttpServer httpServer = HttpServer.create("localhost", 8080); + return httpServer.newHandler(adapter).block(); + } + +} diff --git a/spring-5/src/main/java/com/baeldung/functional/ExploreSpring5URLPatternUsingRouterFunctions.java b/spring-5/src/main/java/com/baeldung/functional/ExploreSpring5URLPatternUsingRouterFunctions.java index b7436c5ba7..2a6d04538c 100644 --- a/spring-5/src/main/java/com/baeldung/functional/ExploreSpring5URLPatternUsingRouterFunctions.java +++ b/spring-5/src/main/java/com/baeldung/functional/ExploreSpring5URLPatternUsingRouterFunctions.java @@ -33,7 +33,7 @@ public class ExploreSpring5URLPatternUsingRouterFunctions { WebServer start() throws Exception { WebHandler webHandler = (WebHandler) toHttpHandler(routingFunction()); HttpHandler httpHandler = WebHttpHandlerBuilder.webHandler(webHandler) - .prependFilter(new IndexRewriteFilter()) + .filter(new IndexRewriteFilter()) .build(); Tomcat tomcat = new Tomcat(); diff --git a/spring-5/src/main/java/com/baeldung/functional/FormHandler.java b/spring-5/src/main/java/com/baeldung/functional/FormHandler.java index 857d22a67f..05069735bb 100644 --- a/spring-5/src/main/java/com/baeldung/functional/FormHandler.java +++ b/spring-5/src/main/java/com/baeldung/functional/FormHandler.java @@ -17,28 +17,25 @@ import static org.springframework.web.reactive.function.server.ServerResponse.ok public class FormHandler { Mono handleLogin(ServerRequest request) { - return request - .body(toFormData()) - .map(MultiValueMap::toSingleValueMap) - .filter(formData -> "baeldung".equals(formData.get("user"))) - .filter(formData -> "you_know_what_to_do".equals(formData.get("token"))) - .flatMap(formData -> ok().body(Mono.just("welcome back!"), String.class)) - .switchIfEmpty(ServerResponse.badRequest().build()); + return request.body(toFormData()) + .map(MultiValueMap::toSingleValueMap) + .filter(formData -> "baeldung".equals(formData.get("user"))) + .filter(formData -> "you_know_what_to_do".equals(formData.get("token"))) + .flatMap(formData -> ok().body(Mono.just("welcome back!"), String.class)) + .switchIfEmpty(ServerResponse.badRequest() + .build()); } Mono handleUpload(ServerRequest request) { - return request - .body(toDataBuffers()) - .collectList() - .flatMap(dataBuffers -> ok() - .body(fromObject(extractData(dataBuffers).toString()))); + return request.body(toDataBuffers()) + .collectList() + .flatMap(dataBuffers -> ok().body(fromObject(extractData(dataBuffers).toString()))); } private AtomicLong extractData(List dataBuffers) { AtomicLong atomicLong = new AtomicLong(0); - dataBuffers.forEach(d -> atomicLong.addAndGet(d - .asByteBuffer() - .array().length)); + dataBuffers.forEach(d -> atomicLong.addAndGet(d.asByteBuffer() + .array().length)); return atomicLong; } } diff --git a/spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java b/spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java index 8a808fc83a..402b607b19 100644 --- a/spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java +++ b/spring-5/src/main/java/com/baeldung/functional/FunctionalSpringBootApplication.java @@ -1,5 +1,17 @@ package com.baeldung.functional; +import static org.springframework.web.reactive.function.BodyInserters.fromObject; +import static org.springframework.web.reactive.function.server.RequestPredicates.GET; +import static org.springframework.web.reactive.function.server.RequestPredicates.POST; +import static org.springframework.web.reactive.function.server.RequestPredicates.path; +import static org.springframework.web.reactive.function.server.RouterFunctions.route; +import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler; +import static org.springframework.web.reactive.function.server.ServerResponse.ok; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletRegistrationBean; @@ -17,18 +29,9 @@ import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.server.WebHandler; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; + import reactor.core.publisher.Flux; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import static org.springframework.web.reactive.function.BodyInserters.fromObject; -import static org.springframework.web.reactive.function.server.RequestPredicates.*; -import static org.springframework.web.reactive.function.server.RouterFunctions.route; -import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler; -import static org.springframework.web.reactive.function.server.ServerResponse.ok; - @SpringBootApplication @ComponentScan(basePackages = { "com.baeldung.functional" }) public class FunctionalSpringBootApplication { @@ -40,28 +43,25 @@ public class FunctionalSpringBootApplication { private RouterFunction routingFunction() { FormHandler formHandler = new FormHandler(); - RouterFunction restfulRouter = route(GET("/"), serverRequest -> ok().body(Flux.fromIterable(actors), Actor.class)).andRoute(POST("/"), serverRequest -> serverRequest - .bodyToMono(Actor.class) - .doOnNext(actors::add) - .then(ok().build())); + RouterFunction restfulRouter = route(GET("/"), serverRequest -> ok().body(Flux.fromIterable(actors), Actor.class)).andRoute(POST("/"), serverRequest -> serverRequest.bodyToMono(Actor.class) + .doOnNext(actors::add) + .then(ok().build())); - return route(GET("/test"), serverRequest -> ok().body(fromObject("helloworld"))) - .andRoute(POST("/login"), formHandler::handleLogin) - .andRoute(POST("/upload"), formHandler::handleUpload) - .and(RouterFunctions.resources("/files/**", new ClassPathResource("files/"))) - .andNest(path("/actor"), restfulRouter) - .filter((request, next) -> { - System.out.println("Before handler invocation: " + request.path()); - return next.handle(request); - }); + return route(GET("/test"), serverRequest -> ok().body(fromObject("helloworld"))).andRoute(POST("/login"), formHandler::handleLogin) + .andRoute(POST("/upload"), formHandler::handleUpload) + .and(RouterFunctions.resources("/files/**", new ClassPathResource("files/"))) + .andNest(path("/actor"), restfulRouter) + .filter((request, next) -> { + System.out.println("Before handler invocation: " + request.path()); + return next.handle(request); + }); } @Bean public ServletRegistrationBean servletRegistrationBean() throws Exception { - HttpHandler httpHandler = WebHttpHandlerBuilder - .webHandler((WebHandler) toHttpHandler(routingFunction())) - .prependFilter(new IndexRewriteFilter()) - .build(); + HttpHandler httpHandler = WebHttpHandlerBuilder.webHandler((WebHandler) toHttpHandler(routingFunction())) + .filter(new IndexRewriteFilter()) + .build(); ServletRegistrationBean registrationBean = new ServletRegistrationBean<>(new RootServlet(httpHandler), "/"); registrationBean.setLoadOnStartup(1); registrationBean.setAsyncSupported(true); @@ -74,10 +74,9 @@ public class FunctionalSpringBootApplication { static class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(final HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest() - .permitAll(); + http.authorizeRequests() + .anyRequest() + .permitAll(); } } diff --git a/spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java b/spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java index 29f9ea43da..5a7d70d3db 100644 --- a/spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java +++ b/spring-5/src/main/java/com/baeldung/functional/FunctionalWebApplication.java @@ -1,5 +1,17 @@ package com.baeldung.functional; +import static org.springframework.web.reactive.function.BodyInserters.fromObject; +import static org.springframework.web.reactive.function.server.RequestPredicates.GET; +import static org.springframework.web.reactive.function.server.RequestPredicates.POST; +import static org.springframework.web.reactive.function.server.RequestPredicates.path; +import static org.springframework.web.reactive.function.server.RouterFunctions.route; +import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler; +import static org.springframework.web.reactive.function.server.ServerResponse.ok; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + import org.apache.catalina.Context; import org.apache.catalina.startup.Tomcat; import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; @@ -12,18 +24,9 @@ import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.server.WebHandler; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; + import reactor.core.publisher.Flux; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -import static org.springframework.web.reactive.function.BodyInserters.fromObject; -import static org.springframework.web.reactive.function.server.RequestPredicates.*; -import static org.springframework.web.reactive.function.server.RouterFunctions.route; -import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler; -import static org.springframework.web.reactive.function.server.ServerResponse.ok; - public class FunctionalWebApplication { private static final Actor BRAD_PITT = new Actor("Brad", "Pitt"); @@ -33,28 +36,25 @@ public class FunctionalWebApplication { private RouterFunction routingFunction() { FormHandler formHandler = new FormHandler(); - RouterFunction restfulRouter = route(GET("/"), serverRequest -> ok().body(Flux.fromIterable(actors), Actor.class)).andRoute(POST("/"), serverRequest -> serverRequest - .bodyToMono(Actor.class) - .doOnNext(actors::add) - .then(ok().build())); + RouterFunction restfulRouter = route(GET("/"), serverRequest -> ok().body(Flux.fromIterable(actors), Actor.class)).andRoute(POST("/"), serverRequest -> serverRequest.bodyToMono(Actor.class) + .doOnNext(actors::add) + .then(ok().build())); - return route(GET("/test"), serverRequest -> ok().body(fromObject("helloworld"))) - .andRoute(POST("/login"), formHandler::handleLogin) - .andRoute(POST("/upload"), formHandler::handleUpload) - .and(RouterFunctions.resources("/files/**", new ClassPathResource("files/"))) - .andNest(path("/actor"), restfulRouter) - .filter((request, next) -> { - System.out.println("Before handler invocation: " + request.path()); - return next.handle(request); - }); + return route(GET("/test"), serverRequest -> ok().body(fromObject("helloworld"))).andRoute(POST("/login"), formHandler::handleLogin) + .andRoute(POST("/upload"), formHandler::handleUpload) + .and(RouterFunctions.resources("/files/**", new ClassPathResource("files/"))) + .andNest(path("/actor"), restfulRouter) + .filter((request, next) -> { + System.out.println("Before handler invocation: " + request.path()); + return next.handle(request); + }); } WebServer start() throws Exception { WebHandler webHandler = (WebHandler) toHttpHandler(routingFunction()); - HttpHandler httpHandler = WebHttpHandlerBuilder - .webHandler(webHandler) - .prependFilter(new IndexRewriteFilter()) - .build(); + HttpHandler httpHandler = WebHttpHandlerBuilder.webHandler(webHandler) + .filter(new IndexRewriteFilter()) + .build(); Tomcat tomcat = new Tomcat(); tomcat.setHostname("localhost"); diff --git a/spring-5/src/main/java/com/baeldung/functional/IndexRewriteFilter.java b/spring-5/src/main/java/com/baeldung/functional/IndexRewriteFilter.java index d218bba581..3e91a0354b 100644 --- a/spring-5/src/main/java/com/baeldung/functional/IndexRewriteFilter.java +++ b/spring-5/src/main/java/com/baeldung/functional/IndexRewriteFilter.java @@ -11,17 +11,15 @@ class IndexRewriteFilter implements WebFilter { @Override public Mono filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) { ServerHttpRequest request = serverWebExchange.getRequest(); - if (request - .getURI() - .getPath() - .equals("/")) { - return webFilterChain.filter(serverWebExchange - .mutate() - .request(builder -> builder - .method(request.getMethod()) - .contextPath(request.getPath().toString()) - .path("/test")) - .build()); + if (request.getURI() + .getPath() + .equals("/")) { + return webFilterChain.filter(serverWebExchange.mutate() + .request(builder -> builder.method(request.getMethod()) + .contextPath(request.getPath() + .toString()) + .path("/test")) + .build()); } return webFilterChain.filter(serverWebExchange); } diff --git a/spring-5/src/main/java/com/baeldung/functional/MyService.java b/spring-5/src/main/java/com/baeldung/functional/MyService.java index d85a860f06..b7b8b13d8b 100644 --- a/spring-5/src/main/java/com/baeldung/functional/MyService.java +++ b/spring-5/src/main/java/com/baeldung/functional/MyService.java @@ -2,12 +2,10 @@ package com.baeldung.functional; import java.util.Random; -import org.springframework.stereotype.Component; - public class MyService { - public int getRandomNumber(){ + public int getRandomNumber() { return (new Random().nextInt(10)); } - + } diff --git a/spring-5/src/main/java/com/baeldung/functional/RootServlet.java b/spring-5/src/main/java/com/baeldung/functional/RootServlet.java index 922809e563..8fe24821de 100644 --- a/spring-5/src/main/java/com/baeldung/functional/RootServlet.java +++ b/spring-5/src/main/java/com/baeldung/functional/RootServlet.java @@ -1,5 +1,20 @@ package com.baeldung.functional; +import static org.springframework.web.reactive.function.BodyExtractors.toDataBuffers; +import static org.springframework.web.reactive.function.BodyExtractors.toFormData; +import static org.springframework.web.reactive.function.BodyInserters.fromObject; +import static org.springframework.web.reactive.function.server.RequestPredicates.GET; +import static org.springframework.web.reactive.function.server.RequestPredicates.POST; +import static org.springframework.web.reactive.function.server.RequestPredicates.path; +import static org.springframework.web.reactive.function.server.RouterFunctions.route; +import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler; +import static org.springframework.web.reactive.function.server.ServerResponse.ok; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicLong; + import org.springframework.core.io.ClassPathResource; import org.springframework.http.server.reactive.HttpHandler; import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; @@ -7,31 +22,18 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.WebHandler; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicLong; - -import static org.springframework.web.reactive.function.BodyExtractors.toDataBuffers; -import static org.springframework.web.reactive.function.BodyExtractors.toFormData; -import static org.springframework.web.reactive.function.BodyInserters.fromObject; -import static org.springframework.web.reactive.function.server.RequestPredicates.*; -import static org.springframework.web.reactive.function.server.RouterFunctions.route; -import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler; -import static org.springframework.web.reactive.function.server.ServerResponse.ok; -import org.springframework.web.server.WebHandler; - public class RootServlet extends ServletHttpHandlerAdapter { public RootServlet() { - this(WebHttpHandlerBuilder - .webHandler((WebHandler) toHttpHandler(routingFunction())) - .prependFilter(new IndexRewriteFilter()) - .build()); + this(WebHttpHandlerBuilder.webHandler((WebHandler) toHttpHandler(routingFunction())) + .filter(new IndexRewriteFilter()) + .build()); } RootServlet(HttpHandler httpHandler) { @@ -44,44 +46,36 @@ public class RootServlet extends ServletHttpHandlerAdapter { private static RouterFunction routingFunction() { - return route(GET("/test"), serverRequest -> ok().body(fromObject("helloworld"))) - .andRoute(POST("/login"), serverRequest -> serverRequest - .body(toFormData()) + return route(GET("/test"), serverRequest -> ok().body(fromObject("helloworld"))).andRoute(POST("/login"), serverRequest -> serverRequest.body(toFormData()) .map(MultiValueMap::toSingleValueMap) .map(formData -> { System.out.println("form data: " + formData.toString()); if ("baeldung".equals(formData.get("user")) && "you_know_what_to_do".equals(formData.get("token"))) { - return ok() - .body(Mono.just("welcome back!"), String.class) - .block(); + return ok().body(Mono.just("welcome back!"), String.class) + .block(); } - return ServerResponse - .badRequest() - .build() - .block(); + return ServerResponse.badRequest() + .build() + .block(); })) - .andRoute(POST("/upload"), serverRequest -> serverRequest - .body(toDataBuffers()) - .collectList() - .map(dataBuffers -> { - AtomicLong atomicLong = new AtomicLong(0); - dataBuffers.forEach(d -> atomicLong.addAndGet(d - .asByteBuffer() - .array().length)); - System.out.println("data length:" + atomicLong.get()); - return ok() - .body(fromObject(atomicLong.toString())) - .block(); - })) - .and(RouterFunctions.resources("/files/**", new ClassPathResource("files/"))) - .andNest(path("/actor"), route(GET("/"), serverRequest -> ok().body(Flux.fromIterable(actors), Actor.class)).andRoute(POST("/"), serverRequest -> serverRequest - .bodyToMono(Actor.class) - .doOnNext(actors::add) - .then(ok().build()))) - .filter((request, next) -> { - System.out.println("Before handler invocation: " + request.path()); - return next.handle(request); - }); + .andRoute(POST("/upload"), serverRequest -> serverRequest.body(toDataBuffers()) + .collectList() + .map(dataBuffers -> { + AtomicLong atomicLong = new AtomicLong(0); + dataBuffers.forEach(d -> atomicLong.addAndGet(d.asByteBuffer() + .array().length)); + System.out.println("data length:" + atomicLong.get()); + return ok().body(fromObject(atomicLong.toString())) + .block(); + })) + .and(RouterFunctions.resources("/files/**", new ClassPathResource("files/"))) + .andNest(path("/actor"), route(GET("/"), serverRequest -> ok().body(Flux.fromIterable(actors), Actor.class)).andRoute(POST("/"), serverRequest -> serverRequest.bodyToMono(Actor.class) + .doOnNext(actors::add) + .then(ok().build()))) + .filter((request, next) -> { + System.out.println("Before handler invocation: " + request.path()); + return next.handle(request); + }); } diff --git a/spring-5/src/main/java/com/baeldung/jsonb/Person.java b/spring-5/src/main/java/com/baeldung/jsonb/Person.java new file mode 100644 index 0000000000..7a54b37574 --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/jsonb/Person.java @@ -0,0 +1,127 @@ +package com.baeldung.jsonb; + +import java.math.BigDecimal; +import java.time.LocalDate; + +import javax.json.bind.annotation.JsonbDateFormat; +import javax.json.bind.annotation.JsonbNumberFormat; +import javax.json.bind.annotation.JsonbProperty; +import javax.json.bind.annotation.JsonbTransient; + +public class Person { + + private int id; + @JsonbProperty("person-name") + private String name; + @JsonbProperty(nillable = true) + private String email; + @JsonbTransient + private int age; + @JsonbDateFormat("dd-MM-yyyy") + private LocalDate registeredDate; + private BigDecimal salary; + + public Person() { + } + + public Person(int id, String name, String email, int age, LocalDate registeredDate, BigDecimal salary) { + super(); + this.id = id; + this.name = name; + this.email = email; + this.age = age; + this.registeredDate = registeredDate; + this.salary = salary; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @JsonbNumberFormat(locale = "en_US", value = "#0.0") + public BigDecimal getSalary() { + return salary; + } + + public void setSalary(BigDecimal salary) { + this.salary = salary; + } + + public LocalDate getRegisteredDate() { + return registeredDate; + } + + public void setRegisteredDate(LocalDate registeredDate) { + this.registeredDate = registeredDate; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Person [id="); + builder.append(id); + builder.append(", name="); + builder.append(name); + builder.append(", email="); + builder.append(email); + builder.append(", age="); + builder.append(age); + builder.append(", registeredDate="); + builder.append(registeredDate); + builder.append(", salary="); + builder.append(salary); + builder.append("]"); + return builder.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + id; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Person other = (Person) obj; + if (id != other.id) + return false; + return true; + } + +} diff --git a/spring-5/src/main/java/com/baeldung/jsonb/PersonController.java b/spring-5/src/main/java/com/baeldung/jsonb/PersonController.java new file mode 100644 index 0000000000..e216a282eb --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/jsonb/PersonController.java @@ -0,0 +1,58 @@ +package com.baeldung.jsonb; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.annotation.PostConstruct; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController("/person") +public class PersonController { + + List personRepository; + + @PostConstruct + public void init() { + // @formatter:off + personRepository = new ArrayList<>(Arrays.asList( + new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)), + new Person(2, "Jhon", "jhon1@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500)), + new Person(3, "Jhon", null, 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)), + new Person(4, "Tom", "tom@test.com", 21, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500)), + new Person(5, "Mark", "mark@test.com", 21, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1200)), + new Person(6, "Julia", "jhon@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)))); + // @formatter:on + + } + + @GetMapping("/person/{id}") + @ResponseBody + public Person findById(@PathVariable final int id) { + return personRepository.get(id); + } + + @PostMapping("/person") + @ResponseStatus(HttpStatus.OK) + @ResponseBody + public boolean insertPerson(@RequestBody final Person person) { + return personRepository.add(person); + } + + @GetMapping("/person") + @ResponseBody + public List findAll() { + return personRepository; + } + +} diff --git a/spring-5/src/main/java/com/baeldung/jsonb/Spring5Application.java b/spring-5/src/main/java/com/baeldung/jsonb/Spring5Application.java new file mode 100644 index 0000000000..00fce06834 --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/jsonb/Spring5Application.java @@ -0,0 +1,30 @@ +package com.baeldung.jsonb; + +import java.util.ArrayList; +import java.util.Collection; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.JsonbHttpMessageConverter; + +@SpringBootApplication +@ComponentScan(basePackages = { "com.baeldung.jsonb" }) +public class Spring5Application { + + public static void main(String[] args) { + SpringApplication.run(Spring5Application.class, args); + } + + @Bean + public HttpMessageConverters customConverters() { + Collection> messageConverters = new ArrayList<>(); + JsonbHttpMessageConverter jsonbHttpMessageConverter = new JsonbHttpMessageConverter(); + messageConverters.add(jsonbHttpMessageConverter); + return new HttpMessageConverters(true, messageConverters); + } + +} diff --git a/spring-5/src/main/java/com/baeldung/jupiter/ParameterAutowireUtils.java b/spring-5/src/main/java/com/baeldung/jupiter/ParameterAutowireUtils.java index 068c6af381..d1a4cc8b29 100644 --- a/spring-5/src/main/java/com/baeldung/jupiter/ParameterAutowireUtils.java +++ b/spring-5/src/main/java/com/baeldung/jupiter/ParameterAutowireUtils.java @@ -27,16 +27,14 @@ abstract class ParameterAutowireUtils { public static Object resolveDependency(Parameter parameter, Class containingClass, ApplicationContext applicationContext) { - boolean required = findMergedAnnotation(parameter, Autowired.class) - .map(Autowired::required) - .orElse(true); + boolean required = findMergedAnnotation(parameter, Autowired.class).map(Autowired::required) + .orElse(true); MethodParameter methodParameter = (parameter.getDeclaringExecutable() instanceof Method ? MethodParameterFactory.createSynthesizingMethodParameter(parameter) : MethodParameterFactory.createMethodParameter(parameter)); DependencyDescriptor descriptor = new DependencyDescriptor(methodParameter, required); descriptor.setContainingClass(containingClass); - return applicationContext - .getAutowireCapableBeanFactory() - .resolveDependency(descriptor, null); + return applicationContext.getAutowireCapableBeanFactory() + .resolveDependency(descriptor, null); } private static Optional findMergedAnnotation(AnnotatedElement element, Class annotationType) { diff --git a/spring-5/src/main/java/com/baeldung/jupiter/SpringExtension.java b/spring-5/src/main/java/com/baeldung/jupiter/SpringExtension.java index 08fa0c4768..7218d984ef 100644 --- a/spring-5/src/main/java/com/baeldung/jupiter/SpringExtension.java +++ b/spring-5/src/main/java/com/baeldung/jupiter/SpringExtension.java @@ -1,36 +1,42 @@ package com.baeldung.jupiter; -import org.junit.jupiter.api.extension.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.test.context.TestContextManager; -import org.springframework.util.Assert; - import java.lang.reflect.Constructor; import java.lang.reflect.Executable; import java.lang.reflect.Method; import java.lang.reflect.Parameter; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.jupiter.api.extension.TestInstancePostProcessor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.test.context.TestContextManager; +import org.springframework.util.Assert; + public class SpringExtension implements BeforeAllCallback, AfterAllCallback, TestInstancePostProcessor, BeforeEachCallback, AfterEachCallback, ParameterResolver { private static final ExtensionContext.Namespace namespace = ExtensionContext.Namespace.create(SpringExtension.class); @Override - public void beforeAll(ContainerExtensionContext context) throws Exception { + public void beforeAll(ExtensionContext context) throws Exception { getTestContextManager(context).beforeTestClass(); } @Override - public void afterAll(ContainerExtensionContext context) throws Exception { + public void afterAll(ExtensionContext context) throws Exception { try { getTestContextManager(context).afterTestClass(); } finally { - context - .getStore(namespace) - .remove(context - .getTestClass() - .get()); + context.getStore(namespace) + .remove(context.getTestClass() + .get()); } } @@ -40,54 +46,48 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes } @Override - public void beforeEach(TestExtensionContext context) throws Exception { + public void beforeEach(ExtensionContext context) throws Exception { Object testInstance = context.getTestInstance(); - Method testMethod = context - .getTestMethod() - .get(); + Method testMethod = context.getTestMethod() + .get(); getTestContextManager(context).beforeTestMethod(testInstance, testMethod); } @Override - public void afterEach(TestExtensionContext context) throws Exception { + public void afterEach(ExtensionContext context) throws Exception { Object testInstance = context.getTestInstance(); - Method testMethod = context - .getTestMethod() - .get(); - Throwable testException = context - .getTestException() - .orElse(null); + Method testMethod = context.getTestMethod() + .get(); + Throwable testException = context.getExecutionException() + .orElse(null); getTestContextManager(context).afterTestMethod(testInstance, testMethod, testException); } @Override - public boolean supports(ParameterContext parameterContext, ExtensionContext extensionContext) { + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { Parameter parameter = parameterContext.getParameter(); Executable executable = parameter.getDeclaringExecutable(); - return (executable instanceof Constructor && AnnotatedElementUtils.hasAnnotation(executable, Autowired.class)) || ParameterAutowireUtils.isAutowirable(parameter); + return ((executable instanceof Constructor) && AnnotatedElementUtils.hasAnnotation(executable, Autowired.class)) || ParameterAutowireUtils.isAutowirable(parameter); } @Override - public Object resolve(ParameterContext parameterContext, ExtensionContext extensionContext) { + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { Parameter parameter = parameterContext.getParameter(); - Class testClass = extensionContext - .getTestClass() - .get(); + Class testClass = extensionContext.getTestClass() + .get(); ApplicationContext applicationContext = getApplicationContext(extensionContext); return ParameterAutowireUtils.resolveDependency(parameter, testClass, applicationContext); } private ApplicationContext getApplicationContext(ExtensionContext context) { - return getTestContextManager(context) - .getTestContext() - .getApplicationContext(); + return getTestContextManager(context).getTestContext() + .getApplicationContext(); } private TestContextManager getTestContextManager(ExtensionContext context) { Assert.notNull(context, "ExtensionContext must not be null"); - Class testClass = context - .getTestClass() - .get(); + Class testClass = context.getTestClass() + .get(); ExtensionContext.Store store = context.getStore(namespace); return store.getOrComputeIfAbsent(testClass, TestContextManager::new, TestContextManager.class); } diff --git a/spring-5/src/main/java/com/baeldung/jupiter/SpringJUnit5Config.java b/spring-5/src/main/java/com/baeldung/jupiter/SpringJUnit5Config.java index e8b9cc500f..8f02d71d49 100644 --- a/spring-5/src/main/java/com/baeldung/jupiter/SpringJUnit5Config.java +++ b/spring-5/src/main/java/com/baeldung/jupiter/SpringJUnit5Config.java @@ -26,8 +26,7 @@ public @interface SpringJUnit5Config { String[] locations() default {}; @AliasFor(annotation = ContextConfiguration.class) - Class>[] initializers() default {}; + Class>[] initializers() default {}; @AliasFor(annotation = ContextConfiguration.class) boolean inheritLocations() default true; diff --git a/spring-5/src/main/java/com/baeldung/persistence/DataSetupBean.java b/spring-5/src/main/java/com/baeldung/persistence/DataSetupBean.java index 7936a2b7af..9f5d9ff6c2 100644 --- a/spring-5/src/main/java/com/baeldung/persistence/DataSetupBean.java +++ b/spring-5/src/main/java/com/baeldung/persistence/DataSetupBean.java @@ -20,7 +20,8 @@ public class DataSetupBean implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { - IntStream.range(1, 20).forEach(i -> repo.save(new Foo(randomAlphabetic(8)))); + IntStream.range(1, 20) + .forEach(i -> repo.save(new Foo(randomAlphabetic(8)))); } } diff --git a/spring-5/src/main/java/com/baeldung/security/GreetController.java b/spring-5/src/main/java/com/baeldung/security/GreetController.java new file mode 100644 index 0000000000..6b69e3bc9b --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/security/GreetController.java @@ -0,0 +1,37 @@ +package com.baeldung.security; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +import java.security.Principal; + +@RestController +public class GreetController { + + private GreetService greetService; + + public GreetController(GreetService greetService) { + this.greetService = greetService; + } + + @GetMapping("/") + public Mono greet(Mono principal) { + return principal + .map(Principal::getName) + .map(name -> String.format("Hello, %s", name)); + } + + @GetMapping("/admin") + public Mono greetAdmin(Mono principal) { + return principal + .map(Principal::getName) + .map(name -> String.format("Admin access: %s", name)); + } + + @GetMapping("/greetService") + public Mono greetService() { + return greetService.greet(); + } + +} diff --git a/spring-5/src/main/java/com/baeldung/security/GreetService.java b/spring-5/src/main/java/com/baeldung/security/GreetService.java new file mode 100644 index 0000000000..7622b360be --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/security/GreetService.java @@ -0,0 +1,15 @@ +package com.baeldung.security; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Mono; + +@Service +public class GreetService { + + @PreAuthorize("hasRole('ADMIN')") + public Mono greet() { + return Mono.just("Hello from service!"); + } + +} diff --git a/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java b/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java new file mode 100644 index 0000000000..a9e44a2eee --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java @@ -0,0 +1,42 @@ +package com.baeldung.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.server.SecurityWebFilterChain; + +@EnableWebFluxSecurity +@EnableReactiveMethodSecurity +public class SecurityConfig { + + @Bean + public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) { + return http.authorizeExchange() + .pathMatchers("/admin").hasAuthority("ROLE_ADMIN") + .anyExchange().authenticated() + .and().formLogin() + .and().build(); + } + + @Bean + public MapReactiveUserDetailsService userDetailsService() { + UserDetails user = User.withDefaultPasswordEncoder() + .username("user") + .password("password") + .roles("USER") + .build(); + + UserDetails admin = User.withDefaultPasswordEncoder() + .username("admin") + .password("password") + .roles("ADMIN") + .build(); + + return new MapReactiveUserDetailsService(user, admin); + } + +} diff --git a/spring-5/src/main/java/com/baeldung/web/FooController.java b/spring-5/src/main/java/com/baeldung/web/FooController.java index 0e7c94bd8f..925f2b49f4 100644 --- a/spring-5/src/main/java/com/baeldung/web/FooController.java +++ b/spring-5/src/main/java/com/baeldung/web/FooController.java @@ -23,7 +23,8 @@ public class FooController { @ResponseBody @Validated public Foo findById(@PathVariable @Min(0) final long id) { - return repo.findById(id).orElse(null); + return repo.findById(id) + .orElse(null); } @GetMapping @@ -36,7 +37,8 @@ public class FooController { @ResponseBody @Validated public List findPaginated(@RequestParam("page") @Min(0) final int page, @Max(100) @RequestParam("size") final int size) { - return repo.findAll(PageRequest.of(page, size)).getContent(); + return repo.findAll(PageRequest.of(page, size)) + .getContent(); } // API - write diff --git a/spring-5/src/main/java/com/baeldung/web/reactive/Task.java b/spring-5/src/main/java/com/baeldung/web/reactive/Task.java index 84193d9354..725fd931e1 100644 --- a/spring-5/src/main/java/com/baeldung/web/reactive/Task.java +++ b/spring-5/src/main/java/com/baeldung/web/reactive/Task.java @@ -23,9 +23,6 @@ public class Task { @Override public String toString() { - return "Task{" + - "name='" + name + '\'' + - ", id=" + id + - '}'; + return "Task{" + "name='" + name + '\'' + ", id=" + id + '}'; } } diff --git a/spring-5/src/main/java/com/baeldung/web/reactive/client/WebClientController.java b/spring-5/src/main/java/com/baeldung/web/reactive/client/WebClientController.java index 3a2e1b1a75..a218c6b7cf 100644 --- a/spring-5/src/main/java/com/baeldung/web/reactive/client/WebClientController.java +++ b/spring-5/src/main/java/com/baeldung/web/reactive/client/WebClientController.java @@ -33,8 +33,10 @@ public class WebClientController { WebClient.UriSpec request2 = createWebClientWithServerURLAndDefaultValues().post(); // request body specifications - WebClient.RequestBodySpec uri1 = createWebClientWithServerURLAndDefaultValues().method(HttpMethod.POST).uri("/resource"); - WebClient.RequestBodySpec uri2 = createWebClientWithServerURLAndDefaultValues().post().uri(URI.create("/resource")); + WebClient.RequestBodySpec uri1 = createWebClientWithServerURLAndDefaultValues().method(HttpMethod.POST) + .uri("/resource"); + WebClient.RequestBodySpec uri2 = createWebClientWithServerURLAndDefaultValues().post() + .uri(URI.create("/resource")); // request header specification WebClient.RequestHeadersSpec requestSpec1 = uri1.body(BodyInserters.fromPublisher(Mono.just("data"), String.class)); @@ -44,7 +46,6 @@ public class WebClientController { BodyInserter, ReactiveHttpOutputMessage> inserter1 = BodyInserters .fromPublisher(Subscriber::onComplete, String.class); - LinkedMultiValueMap map = new LinkedMultiValueMap<>(); map.add("key1", "value1"); map.add("key2", "value2"); @@ -53,14 +54,13 @@ public class WebClientController { BodyInserter inserter3 = BodyInserters.fromObject("body"); // responses - WebClient.ResponseSpec response1 = uri1 - .body(inserter3) - .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML) - .acceptCharset(Charset.forName("UTF-8")) - .ifNoneMatch("*") - .ifModifiedSince(ZonedDateTime.now()) - .retrieve(); + WebClient.ResponseSpec response1 = uri1.body(inserter3) + .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML) + .acceptCharset(Charset.forName("UTF-8")) + .ifNoneMatch("*") + .ifModifiedSince(ZonedDateTime.now()) + .retrieve(); WebClient.ResponseSpec response2 = requestSpec2.retrieve(); } @@ -74,13 +74,12 @@ public class WebClientController { } private WebClient createWebClientWithServerURLAndDefaultValues() { - return WebClient - .builder() - .baseUrl("http://localhost:8081") - .defaultCookie("cookieKey", "cookieValue") - .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) - .defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080")) - .build(); + return WebClient.builder() + .baseUrl("http://localhost:8081") + .defaultCookie("cookieKey", "cookieValue") + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080")) + .build(); } } diff --git a/spring-5/src/main/resources/application.properties b/spring-5/src/main/resources/application.properties index 886ea1978b..ccec014c2b 100644 --- a/spring-5/src/main/resources/application.properties +++ b/spring-5/src/main/resources/application.properties @@ -1,6 +1,3 @@ server.port=8081 -security.user.name=user -security.user.password=pass - logging.level.root=INFO \ No newline at end of file diff --git a/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java b/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java index cbb7a2867b..1ce96de4ef 100644 --- a/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/ParallelIntegrationTest.java @@ -9,14 +9,14 @@ public class ParallelIntegrationTest { @Test public void runTests() { - final Class[] classes = {Example1IntegrationTest.class, Example2IntegrationTest.class}; + final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; JUnitCore.runClasses(new Computer(), classes); } @Test public void runTestsInParallel() { - final Class[] classes = {Example1IntegrationTest.class, Example2IntegrationTest.class}; + final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; JUnitCore.runClasses(new ParallelComputer(true, true), classes); } diff --git a/spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java b/spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java index a155de20fa..7e494465b2 100644 --- a/spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java @@ -50,5 +50,3 @@ public class Spring5JUnit4ConcurrentIntegrationTest implements ApplicationContex } } - - diff --git a/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java b/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java index 6f39f11b00..a7b951b930 100644 --- a/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java @@ -23,10 +23,9 @@ public class FunctionalWebApplicationIntegrationTest { @BeforeClass public static void setup() throws Exception { server = new FunctionalWebApplication().start(); - client = WebTestClient - .bindToServer() - .baseUrl("http://localhost:" + server.getPort()) - .build(); + client = WebTestClient.bindToServer() + .baseUrl("http://localhost:" + server.getPort()) + .build(); } @AfterClass @@ -36,26 +35,24 @@ public class FunctionalWebApplicationIntegrationTest { @Test public void givenRouter_whenGetTest_thenGotHelloWorld() throws Exception { - client - .get() - .uri("/test") - .exchange() - .expectStatus() - .isOk() - .expectBody(String.class) - .isEqualTo("helloworld"); + client.get() + .uri("/test") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("helloworld"); } @Test public void givenIndexFilter_whenRequestRoot_thenRewrittenToTest() throws Exception { - client - .get() - .uri("/") - .exchange() - .expectStatus() - .isOk() - .expectBody(String.class) - .isEqualTo("helloworld"); + client.get() + .uri("/") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("helloworld"); } @Test @@ -64,16 +61,15 @@ public class FunctionalWebApplicationIntegrationTest { formData.add("user", "baeldung"); formData.add("token", "you_know_what_to_do"); - client - .post() - .uri("/login") - .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .body(BodyInserters.fromFormData(formData)) - .exchange() - .expectStatus() - .isOk() - .expectBody(String.class) - .isEqualTo("welcome back!"); + client.post() + .uri("/login") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(BodyInserters.fromFormData(formData)) + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("welcome back!"); } @Test @@ -82,70 +78,64 @@ public class FunctionalWebApplicationIntegrationTest { formData.add("user", "baeldung"); formData.add("token", "try_again"); - client - .post() - .uri("/login") - .contentType(MediaType.APPLICATION_FORM_URLENCODED) - .body(BodyInserters.fromFormData(formData)) - .exchange() - .expectStatus() - .isBadRequest(); + client.post() + .uri("/login") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .body(BodyInserters.fromFormData(formData)) + .exchange() + .expectStatus() + .isBadRequest(); } @Test public void givenUploadForm_whenRequestWithMultipartData_thenSuccess() throws Exception { Resource resource = new ClassPathResource("/baeldung-weekly.png"); - client - .post() - .uri("/upload") - .contentType(MediaType.MULTIPART_FORM_DATA) - .body(fromResource(resource)) - .exchange() - .expectStatus() - .isOk() - .expectBody(String.class) - .isEqualTo(String.valueOf(resource.contentLength())); + client.post() + .uri("/upload") + .contentType(MediaType.MULTIPART_FORM_DATA) + .body(fromResource(resource)) + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo(String.valueOf(resource.contentLength())); } @Test public void givenActors_whenAddActor_thenAdded() throws Exception { - client - .get() - .uri("/actor") - .exchange() - .expectStatus() - .isOk() - .expectBodyList(Actor.class) - .hasSize(2); + client.get() + .uri("/actor") + .exchange() + .expectStatus() + .isOk() + .expectBodyList(Actor.class) + .hasSize(2); - client - .post() - .uri("/actor") - .body(fromObject(new Actor("Clint", "Eastwood"))) - .exchange() - .expectStatus() - .isOk(); + client.post() + .uri("/actor") + .body(fromObject(new Actor("Clint", "Eastwood"))) + .exchange() + .expectStatus() + .isOk(); - client - .get() - .uri("/actor") - .exchange() - .expectStatus() - .isOk() - .expectBodyList(Actor.class) - .hasSize(3); + client.get() + .uri("/actor") + .exchange() + .expectStatus() + .isOk() + .expectBodyList(Actor.class) + .hasSize(3); } @Test public void givenResources_whenAccess_thenGot() throws Exception { - client - .get() - .uri("/files/hello.txt") - .exchange() - .expectStatus() - .isOk() - .expectBody(String.class) - .isEqualTo("hello"); + client.get() + .uri("/files/hello.txt") + .exchange() + .expectStatus() + .isOk() + .expectBody(String.class) + .isEqualTo("hello"); } } diff --git a/spring-5/src/test/java/com/baeldung/jsonb/JsonbIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jsonb/JsonbIntegrationTest.java new file mode 100644 index 0000000000..756b303f3b --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/jsonb/JsonbIntegrationTest.java @@ -0,0 +1,43 @@ +package com.baeldung.jsonb; + +import static org.junit.Assert.assertTrue; + +import java.math.BigDecimal; +import java.time.LocalDate; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Spring5Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class JsonbIntegrationTest { + @Value("${security.user.name}") + private String username; + @Value("${security.user.password}") + private String password; + + @Autowired + private TestRestTemplate template; + + @Test + public void givenId_whenUriIsPerson_thenGetPerson() { + ResponseEntity response = template.withBasicAuth(username, password) + .getForEntity("/person/1", Person.class); + Person person = response.getBody(); + assertTrue(person.equals(new Person(2, "Jhon", "jhon1@test.com", 0, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500.0)))); + } + + @Test + public void whenSendPostAPerson_thenGetOkStatus() { + ResponseEntity response = template.withBasicAuth(username, password) + .postForEntity("/person", "{\"birthDate\":\"07-09-2017\",\"email\":\"jhon1@test.com\",\"person-name\":\"Jhon\",\"id\":10}", Boolean.class); + assertTrue(response.getBody()); + } + +} diff --git a/spring-5/src/test/java/com/baeldung/jupiter/EnabledOnJava8.java b/spring-5/src/test/java/com/baeldung/jupiter/EnabledOnJava8.java new file mode 100644 index 0000000000..c6d3b7ff10 --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/jupiter/EnabledOnJava8.java @@ -0,0 +1,18 @@ +package com.baeldung.jupiter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.test.context.junit.jupiter.EnabledIf; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@EnabledIf( + expression = "#{systemProperties['java.version'].startsWith('1.8')}", + reason = "Enabled on Java 8" +) +public @interface EnabledOnJava8 { + +} diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5EnabledAnnotationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5EnabledAnnotationTest.java new file mode 100644 index 0000000000..ae058bc8ba --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5EnabledAnnotationTest.java @@ -0,0 +1,50 @@ +package com.baeldung.jupiter; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.DisabledIf; +import org.springframework.test.context.junit.jupiter.EnabledIf; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +@SpringJUnitConfig(Spring5EnabledAnnotationTest.Config.class) +@TestPropertySource(properties = { "tests.enabled=true" }) +public class Spring5EnabledAnnotationTest { + + @Configuration + static class Config { + } + + @EnabledIf("true") + @Test + void givenEnabledIfLiteral_WhenTrue_ThenTestExecuted() { + assertTrue(true); + } + + @EnabledIf(expression = "${tests.enabled}", loadContext = true) + @Test + void givenEnabledIfExpression_WhenTrue_ThenTestExecuted() { + assertTrue(true); + } + + @EnabledIf("#{systemProperties['java.version'].startsWith('1.8')}") + @Test + void givenEnabledIfSpel_WhenTrue_ThenTestExecuted() { + assertTrue(true); + } + + @EnabledOnJava8 + @Test + void givenEnabledOnJava8_WhenTrue_ThenTestExecuted() { + assertTrue(true); + } + + @DisabledIf("#{systemProperties['java.version'].startsWith('1.7')}") + @Test + void givenDisabledIf_WhenTrue_ThenTestNotExecuted() { + assertTrue(true); + } + +} diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java index fb6bb27684..55b0fcf267 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5JUnit5ParallelIntegrationTest.java @@ -11,18 +11,14 @@ class Spring5JUnit5ParallelIntegrationTest { @Test void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingParallel() { - final Class[] classes = { - Example1IntegrationTest.class, Example2IntegrationTest.class - }; + final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; JUnitCore.runClasses(new ParallelComputer(true, true), classes); } @Test void givenTwoTestClasses_whenJUnitRunParallel_thenTheTestsExecutingLinear() { - final Class[] classes = { - Example1IntegrationTest.class, Example2IntegrationTest.class - }; + final Class[] classes = { Example1IntegrationTest.class, Example2IntegrationTest.class }; JUnitCore.runClasses(new Computer(), classes); } diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5Java8NewFeaturesIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5Java8NewFeaturesIntegrationTest.java index 2c3a71fb3e..f58bf9f3cd 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5Java8NewFeaturesIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5Java8NewFeaturesIntegrationTest.java @@ -16,18 +16,16 @@ class Spring5Java8NewFeaturesIntegrationTest { } public class StringUtils { - FunctionalInterfaceExample - functionLambdaString = s -> Pattern.compile(" +").splitAsStream(s) - .map(word -> new StringBuilder(word).reverse()) - .collect(Collectors.joining(" ")); + FunctionalInterfaceExample functionLambdaString = s -> Pattern.compile(" +") + .splitAsStream(s) + .map(word -> new StringBuilder(word).reverse()) + .collect(Collectors.joining(" ")); } @Test - void givenStringUtil_whenSupplierCall_thenFunctionalInterfaceReverseString() - throws Exception { + void givenStringUtil_whenSupplierCall_thenFunctionalInterfaceReverseString() throws Exception { Supplier stringUtilsSupplier = StringUtils::new; - assertEquals(stringUtilsSupplier.get().functionLambdaString - .reverseString("hello"), "olleh"); + assertEquals(stringUtilsSupplier.get().functionLambdaString.reverseString("hello"), "olleh"); } } diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java index 5c289c3e34..bbd852d625 100644 --- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5ReactiveServerClientIntegrationTest.java @@ -25,20 +25,15 @@ public class Spring5ReactiveServerClientIntegrationTest { @BeforeAll public static void setUp() throws Exception { HttpServer server = HttpServer.create("localhost", 8080); - RouterFunction route = RouterFunctions - .route(POST("/task/process"), request -> ServerResponse - .ok() - .body(request - .bodyToFlux(Task.class) - .map(ll -> new Task("TaskName", 1)), Task.class)) - .and(RouterFunctions.route(GET("/task"), request -> ServerResponse - .ok() - .body(Mono.just("server is alive"), String.class))); + RouterFunction route = RouterFunctions.route(POST("/task/process"), request -> ServerResponse.ok() + .body(request.bodyToFlux(Task.class) + .map(ll -> new Task("TaskName", 1)), Task.class)) + .and(RouterFunctions.route(GET("/task"), request -> ServerResponse.ok() + .body(Mono.just("server is alive"), String.class))); HttpHandler httpHandler = RouterFunctions.toHttpHandler(route); ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler); - nettyContext = server - .newHandler(adapter) - .block(); + nettyContext = server.newHandler(adapter) + .block(); } @AfterAll @@ -46,55 +41,54 @@ public class Spring5ReactiveServerClientIntegrationTest { nettyContext.dispose(); } -// @Test -// public void givenCheckTask_whenServerHandle_thenServerResponseALiveString() throws Exception { -// WebClient client = WebClient.create("http://localhost:8080"); -// Mono result = client -// .get() -// .uri("/task") -// .exchange() -// .then(response -> response.bodyToMono(String.class)); -// -// assertThat(result.block()).isInstanceOf(String.class); -// } + // @Test + // public void givenCheckTask_whenServerHandle_thenServerResponseALiveString() throws Exception { + // WebClient client = WebClient.create("http://localhost:8080"); + // Mono result = client + // .get() + // .uri("/task") + // .exchange() + // .then(response -> response.bodyToMono(String.class)); + // + // assertThat(result.block()).isInstanceOf(String.class); + // } -// @Test -// public void givenThreeTasks_whenServerHandleTheTasks_thenServerResponseATask() throws Exception { -// URI uri = URI.create("http://localhost:8080/task/process"); -// ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector()); -// ClientRequest request = ClientRequest -// .method(HttpMethod.POST, uri) -// .body(BodyInserters.fromPublisher(getLatLngs(), Task.class)) -// .build(); -// -// Flux taskResponse = exchange -// .exchange(request) -// .flatMap(response -> response.bodyToFlux(Task.class)); -// -// assertThat(taskResponse.blockFirst()).isInstanceOf(Task.class); -// } + // @Test + // public void givenThreeTasks_whenServerHandleTheTasks_thenServerResponseATask() throws Exception { + // URI uri = URI.create("http://localhost:8080/task/process"); + // ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector()); + // ClientRequest request = ClientRequest + // .method(HttpMethod.POST, uri) + // .body(BodyInserters.fromPublisher(getLatLngs(), Task.class)) + // .build(); + // + // Flux taskResponse = exchange + // .exchange(request) + // .flatMap(response -> response.bodyToFlux(Task.class)); + // + // assertThat(taskResponse.blockFirst()).isInstanceOf(Task.class); + // } -// @Test -// public void givenCheckTask_whenServerHandle_thenOragicServerResponseALiveString() throws Exception { -// URI uri = URI.create("http://localhost:8080/task"); -// ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector()); -// ClientRequest request = ClientRequest -// .method(HttpMethod.GET, uri) -// .body(BodyInserters.fromPublisher(getLatLngs(), Task.class)) -// .build(); -// -// Flux taskResponse = exchange -// .exchange(request) -// .flatMap(response -> response.bodyToFlux(String.class)); -// -// assertThat(taskResponse.blockFirst()).isInstanceOf(String.class); -// } + // @Test + // public void givenCheckTask_whenServerHandle_thenOragicServerResponseALiveString() throws Exception { + // URI uri = URI.create("http://localhost:8080/task"); + // ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector()); + // ClientRequest request = ClientRequest + // .method(HttpMethod.GET, uri) + // .body(BodyInserters.fromPublisher(getLatLngs(), Task.class)) + // .build(); + // + // Flux taskResponse = exchange + // .exchange(request) + // .flatMap(response -> response.bodyToFlux(String.class)); + // + // assertThat(taskResponse.blockFirst()).isInstanceOf(String.class); + // } private static Flux getLatLngs() { - return Flux - .range(0, 3) - .zipWith(Flux.interval(Duration.ofSeconds(1))) - .map(x -> new Task("taskname", 1)) - .doOnNext(ll -> System.out.println("Produced: {}" + ll)); + return Flux.range(0, 3) + .zipWith(Flux.interval(Duration.ofSeconds(1))) + .map(x -> new Task("taskname", 1)) + .doOnNext(ll -> System.out.println("Produced: {}" + ll)); } } diff --git a/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitConfigTest.java b/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitConfigTest.java new file mode 100644 index 0000000000..6b0a6f9808 --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitConfigTest.java @@ -0,0 +1,33 @@ +package com.baeldung.jupiter; + +import static org.junit.Assert.assertNotNull; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +/** + * @SpringJUnitConfig(SpringJUnitConfigTest.Config.class) is equivalent to: + * + * @ExtendWith(SpringExtension.class) + * @ContextConfiguration(classes = SpringJUnitConfigTest.Config.class ) + * + */ +@SpringJUnitConfig(SpringJUnitConfigTest.Config.class) +public class SpringJUnitConfigTest { + + @Configuration + static class Config { + } + + @Autowired + private ApplicationContext applicationContext; + + @Test + void givenAppContext_WhenInjected_ThenItShouldNotBeNull() { + assertNotNull(applicationContext); + } + +} diff --git a/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitWebConfigTest.java b/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitWebConfigTest.java new file mode 100644 index 0000000000..c679dce77f --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitWebConfigTest.java @@ -0,0 +1,34 @@ +package com.baeldung.jupiter; + +import static org.junit.Assert.assertNotNull; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig; +import org.springframework.web.context.WebApplicationContext; + +/** + * @SpringJUnitWebConfig(SpringJUnitWebConfigTest.Config.class) is equivalent to: + * + * @ExtendWith(SpringExtension.class) + * @WebAppConfiguration + * @ContextConfiguration(classes = SpringJUnitWebConfigTest.Config.class ) + * + */ +@SpringJUnitWebConfig(SpringJUnitWebConfigTest.Config.class) +public class SpringJUnitWebConfigTest { + + @Configuration + static class Config { + } + + @Autowired + private WebApplicationContext webAppContext; + + @Test + void givenWebAppContext_WhenInjected_ThenItShouldNotBeNull() { + assertNotNull(webAppContext); + } + +} diff --git a/spring-5/src/test/java/com/baeldung/security/SecurityTest.java b/spring-5/src/test/java/com/baeldung/security/SecurityTest.java new file mode 100644 index 0000000000..a1c940a17a --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/security/SecurityTest.java @@ -0,0 +1,48 @@ +package com.baeldung.security; + +import com.baeldung.SpringSecurity5Application; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = SpringSecurity5Application.class) +public class SecurityTest { + + @Autowired + ApplicationContext context; + + private WebTestClient rest; + + @Before + public void setup() { + this.rest = WebTestClient + .bindToApplicationContext(this.context) + .configureClient() + .build(); + } + + @Test + public void whenNoCredentials_thenRedirectToLogin() { + this.rest.get() + .uri("/") + .exchange() + .expectStatus().is3xxRedirection(); + } + + @Test + @WithMockUser + public void whenHasCredentials_thenSeesGreeting() { + this.rest.get() + .uri("/") + .exchange() + .expectStatus().isOk() + .expectBody(String.class).isEqualTo("Hello, user"); + } +} diff --git a/spring-5/src/test/java/com/baeldung/web/PathPatternsUsingHandlerMethodIntegrationTest.java b/spring-5/src/test/java/com/baeldung/web/PathPatternsUsingHandlerMethodIntegrationTest.java index 90e3e7c445..c2ed8ff071 100644 --- a/spring-5/src/test/java/com/baeldung/web/PathPatternsUsingHandlerMethodIntegrationTest.java +++ b/spring-5/src/test/java/com/baeldung/web/PathPatternsUsingHandlerMethodIntegrationTest.java @@ -17,85 +17,85 @@ public class PathPatternsUsingHandlerMethodIntegrationTest { @BeforeClass public static void setUp() { client = WebTestClient.bindToController(new PathPatternController()) - .build(); + .build(); } @Test public void givenHandlerMethod_whenMultipleURIVariablePattern_then200() { client.get() - .uri("/spring5/ab/cd") - .exchange() - .expectStatus() - .is2xxSuccessful() - .expectBody() - .equals("/ab/cd"); + .uri("/spring5/ab/cd") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("/ab/cd"); } @Test public void givenHandlerMethod_whenURLWithWildcardTakingZeroOrMoreChar_then200() { client.get() - .uri("/spring5/userid") - .exchange() - .expectStatus() - .is2xxSuccessful() - .expectBody() - .equals("/spring5/*id"); + .uri("/spring5/userid") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("/spring5/*id"); } @Test public void givenHandlerMethod_whenURLWithWildcardTakingExactlyOneChar_then200() { client.get() - .uri("/string5") - .exchange() - .expectStatus() - .is2xxSuccessful() - .expectBody() - .equals("/s?ring5"); + .uri("/string5") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("/s?ring5"); } @Test public void givenHandlerMethod_whenURLWithWildcardTakingZeroOrMorePathSegments_then200() { client.get() - .uri("/resources/baeldung") - .exchange() - .expectStatus() - .is2xxSuccessful() - .expectBody() - .equals("/resources/**"); + .uri("/resources/baeldung") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("/resources/**"); } @Test public void givenHandlerMethod_whenURLWithRegexInPathVariable_thenExpectedOutput() { client.get() - .uri("/abc") - .exchange() - .expectStatus() - .is2xxSuccessful() - .expectBody() - .equals("abc"); + .uri("/abc") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("abc"); client.get() - .uri("/123") - .exchange() - .expectStatus() - .is4xxClientError(); + .uri("/123") + .exchange() + .expectStatus() + .is4xxClientError(); } @Test public void givenHandlerMethod_whenURLWithMultiplePathVariablesInSameSegment_then200() { client.get() - .uri("/baeldung_tutorial") - .exchange() - .expectStatus() - .is2xxSuccessful() - .expectBody() - .equals("Two variables are var1=baeldung and var2=tutorial"); + .uri("/baeldung_tutorial") + .exchange() + .expectStatus() + .is2xxSuccessful() + .expectBody() + .equals("Two variables are var1=baeldung and var2=tutorial"); } } diff --git a/spring-5/src/test/java/com/baeldung/web/client/WebTestClientTest.java b/spring-5/src/test/java/com/baeldung/web/client/WebTestClientTest.java index 4127f22c01..43114b5b50 100644 --- a/spring-5/src/test/java/com/baeldung/web/client/WebTestClientTest.java +++ b/spring-5/src/test/java/com/baeldung/web/client/WebTestClientTest.java @@ -21,38 +21,40 @@ public class WebTestClientTest { @LocalServerPort private int port; - private final RouterFunction ROUTER_FUNCTION = RouterFunctions.route( - RequestPredicates.GET("/resource"), - request -> ServerResponse.ok().build() - ); + private final RouterFunction ROUTER_FUNCTION = RouterFunctions.route(RequestPredicates.GET("/resource"), request -> ServerResponse.ok() + .build()); private final WebHandler WEB_HANDLER = exchange -> Mono.empty(); @Test public void testWebTestClientWithServerWebHandler() { - WebTestClient.bindToWebHandler(WEB_HANDLER).build(); + WebTestClient.bindToWebHandler(WEB_HANDLER) + .build(); } @Test public void testWebTestClientWithRouterFunction() { - WebTestClient - .bindToRouterFunction(ROUTER_FUNCTION) - .build().get().uri("/resource") - .exchange() - .expectStatus().isOk() - .expectBody().isEmpty(); + WebTestClient.bindToRouterFunction(ROUTER_FUNCTION) + .build() + .get() + .uri("/resource") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .isEmpty(); } @Test public void testWebTestClientWithServerURL() { - WebTestClient - .bindToServer() - .baseUrl("http://localhost:" + port) - .build() - .get() - .uri("/resource") - .exchange() - .expectStatus().is4xxClientError() - .expectBody(); + WebTestClient.bindToServer() + .baseUrl("http://localhost:" + port) + .build() + .get() + .uri("/resource") + .exchange() + .expectStatus() + .is3xxRedirection() + .expectBody(); } } diff --git a/spring-acl/pom.xml b/spring-acl/pom.xml new file mode 100644 index 0000000000..3bcc0cf596 --- /dev/null +++ b/spring-acl/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + com.baeldung + spring-acl + 0.0.1-SNAPSHOT + war + + spring-acl + Spring ACL + + + parent-boot-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-5 + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + + + + org.springframework + spring-test + test + + + + org.springframework.security + spring-security-test + test + + + + org.springframework.security + spring-security-acl + + + org.springframework.security + spring-security-config + + + org.springframework + spring-context-support + + + net.sf.ehcache + ehcache-core + 2.6.11 + jar + + + + + diff --git a/spring-acl/src/main/java/org/baeldung/acl/config/ACLContext.java b/spring-acl/src/main/java/org/baeldung/acl/config/ACLContext.java new file mode 100644 index 0000000000..63a4ea58ef --- /dev/null +++ b/spring-acl/src/main/java/org/baeldung/acl/config/ACLContext.java @@ -0,0 +1,80 @@ +package org.baeldung.acl.config; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.cache.ehcache.EhCacheFactoryBean; +import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.acls.AclPermissionCacheOptimizer; +import org.springframework.security.acls.AclPermissionEvaluator; +import org.springframework.security.acls.domain.AclAuthorizationStrategy; +import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl; +import org.springframework.security.acls.domain.ConsoleAuditLogger; +import org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy; +import org.springframework.security.acls.domain.EhCacheBasedAclCache; +import org.springframework.security.acls.jdbc.BasicLookupStrategy; +import org.springframework.security.acls.jdbc.JdbcMutableAclService; +import org.springframework.security.acls.jdbc.LookupStrategy; +import org.springframework.security.acls.model.PermissionGrantingStrategy; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +@Configuration +@EnableAutoConfiguration +public class ACLContext { + + @Autowired + DataSource dataSource; + + @Bean + public EhCacheBasedAclCache aclCache() { + return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(), permissionGrantingStrategy(), aclAuthorizationStrategy()); + } + + @Bean + public EhCacheFactoryBean aclEhCacheFactoryBean() { + EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean(); + ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject()); + ehCacheFactoryBean.setCacheName("aclCache"); + return ehCacheFactoryBean; + } + + @Bean + public EhCacheManagerFactoryBean aclCacheManager() { + return new EhCacheManagerFactoryBean(); + } + + @Bean + public PermissionGrantingStrategy permissionGrantingStrategy() { + return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()); + } + + @Bean + public AclAuthorizationStrategy aclAuthorizationStrategy() { + return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN")); + } + + @Bean + public MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() { + DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); + AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService()); + expressionHandler.setPermissionEvaluator(permissionEvaluator); + expressionHandler.setPermissionCacheOptimizer(new AclPermissionCacheOptimizer(aclService())); + return expressionHandler; + } + + @Bean + public LookupStrategy lookupStrategy() { + return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger()); + } + + @Bean + public JdbcMutableAclService aclService() { + return new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache()); + } + +} \ No newline at end of file diff --git a/spring-acl/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java b/spring-acl/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java new file mode 100644 index 0000000000..110c4a6d24 --- /dev/null +++ b/spring-acl/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java @@ -0,0 +1,21 @@ +package org.baeldung.acl.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; + +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +public class AclMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration { + + @Autowired + MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler; + + @Override + protected MethodSecurityExpressionHandler createExpressionHandler() { + return defaultMethodSecurityExpressionHandler; + } + +} diff --git a/spring-acl/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java b/spring-acl/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java new file mode 100644 index 0000000000..9b87efa92c --- /dev/null +++ b/spring-acl/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java @@ -0,0 +1,16 @@ +package org.baeldung.acl.config; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories(basePackages = "org.baeldung.acl.persistence.dao") +@PropertySource("classpath:org.baeldung.acl.datasource.properties") +@EntityScan(basePackages={ "org.baeldung.acl.persistence.entity" }) +public class JPAPersistenceConfig { + +} diff --git a/spring-acl/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java b/spring-acl/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java new file mode 100644 index 0000000000..8662c88d6c --- /dev/null +++ b/spring-acl/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java @@ -0,0 +1,24 @@ +package org.baeldung.acl.persistence.dao; + +import java.util.List; + +import org.baeldung.acl.persistence.entity.NoticeMessage; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.security.access.prepost.PostAuthorize; +import org.springframework.security.access.prepost.PostFilter; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface NoticeMessageRepository extends JpaRepository{ + + @PostFilter("hasPermission(filterObject, 'READ')") + List findAll(); + + @PostAuthorize("hasPermission(returnObject, 'READ')") + NoticeMessage findById(Integer id); + + @SuppressWarnings("unchecked") + @PreAuthorize("hasPermission(#noticeMessage, 'WRITE')") + NoticeMessage save(@Param("noticeMessage")NoticeMessage noticeMessage); + +} diff --git a/spring-acl/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java b/spring-acl/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java new file mode 100644 index 0000000000..23f01a8edb --- /dev/null +++ b/spring-acl/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java @@ -0,0 +1,29 @@ +package org.baeldung.acl.persistence.entity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name="system_message") +public class NoticeMessage { + + @Id + @Column + private Integer id; + @Column + private String content; + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public String getContent() { + return content; + } + public void setContent(String content) { + this.content = content; + } +} \ No newline at end of file diff --git a/spring-acl/src/main/resources/acl-data.sql b/spring-acl/src/main/resources/acl-data.sql new file mode 100644 index 0000000000..6c01eaacc2 --- /dev/null +++ b/spring-acl/src/main/resources/acl-data.sql @@ -0,0 +1,28 @@ +INSERT INTO system_message(id,content) VALUES (1,'First Level Message'); +INSERT INTO system_message(id,content) VALUES (2,'Second Level Message'); +INSERT INTO system_message(id,content) VALUES (3,'Third Level Message'); + +INSERT INTO acl_class (id, class) VALUES +(1, 'org.baeldung.acl.persistence.entity.NoticeMessage'); + +INSERT INTO acl_sid (id, principal, sid) VALUES +(1, 1, 'manager'), +(2, 1, 'hr'), +(3, 1, 'admin'), +(4, 0, 'ROLE_EDITOR'); + +INSERT INTO acl_object_identity (id, object_id_class, object_id_identity, parent_object, owner_sid, entries_inheriting) VALUES +(1, 1, 1, NULL, 3, 0), +(2, 1, 2, NULL, 3, 0), +(3, 1, 3, NULL, 3, 0) +; + +INSERT INTO acl_entry (id, acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure) VALUES +(1, 1, 1, 1, 1, 1, 1, 1), +(2, 1, 2, 1, 2, 1, 1, 1), +(3, 1, 3, 4, 1, 1, 1, 1), +(4, 2, 1, 2, 1, 1, 1, 1), +(5, 2, 2, 4, 1, 1, 1, 1), +(6, 3, 1, 4, 1, 1, 1, 1), +(7, 3, 2, 4, 2, 1, 1, 1) +; \ No newline at end of file diff --git a/spring-acl/src/main/resources/acl-schema.sql b/spring-acl/src/main/resources/acl-schema.sql new file mode 100644 index 0000000000..58e9394b2b --- /dev/null +++ b/spring-acl/src/main/resources/acl-schema.sql @@ -0,0 +1,58 @@ +create table system_message (id integer not null, content varchar(255), primary key (id)); + +CREATE TABLE IF NOT EXISTS acl_sid ( + id bigint(20) NOT NULL AUTO_INCREMENT, + principal tinyint(1) NOT NULL, + sid varchar(100) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_1 (sid,principal) +); + +CREATE TABLE IF NOT EXISTS acl_class ( + id bigint(20) NOT NULL AUTO_INCREMENT, + class varchar(255) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_2 (class) +); + +CREATE TABLE IF NOT EXISTS acl_entry ( + id bigint(20) NOT NULL AUTO_INCREMENT, + acl_object_identity bigint(20) NOT NULL, + ace_order int(11) NOT NULL, + sid bigint(20) NOT NULL, + mask int(11) NOT NULL, + granting tinyint(1) NOT NULL, + audit_success tinyint(1) NOT NULL, + audit_failure tinyint(1) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_4 (acl_object_identity,ace_order) +); + +CREATE TABLE IF NOT EXISTS acl_object_identity ( + id bigint(20) NOT NULL AUTO_INCREMENT, + object_id_class bigint(20) NOT NULL, + object_id_identity bigint(20) NOT NULL, + parent_object bigint(20) DEFAULT NULL, + owner_sid bigint(20) DEFAULT NULL, + entries_inheriting tinyint(1) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_3 (object_id_class,object_id_identity) +); + +ALTER TABLE acl_entry +ADD FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity(id); + +ALTER TABLE acl_entry +ADD FOREIGN KEY (sid) REFERENCES acl_sid(id); + +-- +-- Constraints for table acl_object_identity +-- +ALTER TABLE acl_object_identity +ADD FOREIGN KEY (parent_object) REFERENCES acl_object_identity (id); + +ALTER TABLE acl_object_identity +ADD FOREIGN KEY (object_id_class) REFERENCES acl_class (id); + +ALTER TABLE acl_object_identity +ADD FOREIGN KEY (owner_sid) REFERENCES acl_sid (id); \ No newline at end of file diff --git a/spring-acl/src/main/resources/org.baeldung.acl.datasource.properties b/spring-acl/src/main/resources/org.baeldung.acl.datasource.properties new file mode 100644 index 0000000000..739dd3f07c --- /dev/null +++ b/spring-acl/src/main/resources/org.baeldung.acl.datasource.properties @@ -0,0 +1,12 @@ +spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.username=sa +spring.datasource.password= +spring.datasource.driverClassName=org.h2.Driver +spring.jpa.hibernate.ddl-auto=update +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect + +spring.h2.console.path=/myconsole +spring.h2.console.enabled=true +spring.datasource.initialize=true +spring.datasource.schema=classpath:acl-schema.sql +spring.datasource.data=classpath:acl-data.sql \ No newline at end of file diff --git a/spring-acl/src/test/java/org/baeldung/acl/SpringAclTest.java b/spring-acl/src/test/java/org/baeldung/acl/SpringAclTest.java new file mode 100644 index 0000000000..fd9069d9bc --- /dev/null +++ b/spring-acl/src/test/java/org/baeldung/acl/SpringAclTest.java @@ -0,0 +1,119 @@ +package org.baeldung.acl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; + +import org.baeldung.acl.persistence.dao.NoticeMessageRepository; +import org.baeldung.acl.persistence.entity.NoticeMessage; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; +import org.springframework.test.context.support.DirtiesContextTestExecutionListener; +import org.springframework.test.context.transaction.TransactionalTestExecutionListener; +import org.springframework.test.context.web.ServletTestExecutionListener; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestExecutionListeners(listeners={ServletTestExecutionListener.class, + DependencyInjectionTestExecutionListener.class, + DirtiesContextTestExecutionListener.class, + TransactionalTestExecutionListener.class, + WithSecurityContextTestExecutionListener.class}) +public class SpringAclTest extends AbstractJUnit4SpringContextTests{ + + private static Integer FIRST_MESSAGE_ID = 1; + private static Integer SECOND_MESSAGE_ID = 2; + private static Integer THIRD_MESSAGE_ID = 3; + private static String EDITTED_CONTENT = "EDITED"; + + @Configuration + @ComponentScan("org.baeldung.acl.*") + public static class SpringConfig { + + } + + @Autowired + NoticeMessageRepository repo; + + @Test + @WithMockUser(username="manager") + public void givenUsernameManager_whenFindAllMessage_thenReturnFirstMessage(){ + List details = repo.findAll(); + assertNotNull(details); + assertEquals(1,details.size()); + assertEquals(FIRST_MESSAGE_ID,details.get(0).getId()); + } + + @Test + @WithMockUser(username="manager") + public void givenUsernameManager_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenOK(){ + NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID); + assertNotNull(firstMessage); + assertEquals(FIRST_MESSAGE_ID,firstMessage.getId()); + + firstMessage.setContent(EDITTED_CONTENT); + repo.save(firstMessage); + + NoticeMessage editedFirstMessage = repo.findById(FIRST_MESSAGE_ID); + assertNotNull(editedFirstMessage); + assertEquals(FIRST_MESSAGE_ID,editedFirstMessage.getId()); + assertEquals(EDITTED_CONTENT,editedFirstMessage.getContent()); + } + + @Test + @WithMockUser(username="hr") + public void givenUsernameHr_whenFindMessageById2_thenOK(){ + NoticeMessage secondMessage = repo.findById(SECOND_MESSAGE_ID); + assertNotNull(secondMessage); + assertEquals(SECOND_MESSAGE_ID,secondMessage.getId()); + } + + @Test(expected=AccessDeniedException.class) + @WithMockUser(username="hr") + public void givenUsernameHr_whenUpdateMessageWithId2_thenFail(){ + NoticeMessage secondMessage = new NoticeMessage(); + secondMessage.setId(SECOND_MESSAGE_ID); + secondMessage.setContent(EDITTED_CONTENT); + repo.save(secondMessage); + } + + @Test + @WithMockUser(roles={"EDITOR"}) + public void givenRoleEditor_whenFindAllMessage_thenReturnThreeMessage(){ + List details = repo.findAll(); + assertNotNull(details); + assertEquals(3,details.size()); + } + + @Test + @WithMockUser(roles={"EDITOR"}) + public void givenRoleEditor_whenUpdateThirdMessage_thenOK(){ + NoticeMessage thirdMessage = new NoticeMessage(); + thirdMessage.setId(THIRD_MESSAGE_ID); + thirdMessage.setContent(EDITTED_CONTENT); + repo.save(thirdMessage); + } + + @Test(expected=AccessDeniedException.class) + @WithMockUser(roles={"EDITOR"}) + public void givenRoleEditor_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenFail(){ + NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID); + assertNotNull(firstMessage); + assertEquals(FIRST_MESSAGE_ID,firstMessage.getId()); + firstMessage.setContent(EDITTED_CONTENT); + repo.save(firstMessage); + } +} + \ No newline at end of file diff --git a/spring-activiti/README.md b/spring-activiti/README.md index fc6eea7f87..703dfeec52 100644 --- a/spring-activiti/README.md +++ b/spring-activiti/README.md @@ -1,3 +1,6 @@ ### Relevant articles - [A Guide to Activiti with Java](http://www.baeldung.com/java-activiti) +- [Introduction to Activiti with Spring](http://www.baeldung.com/spring-activiti) +- [Activiti with Spring Security](http://www.baeldung.com/activiti-spring-security) +- [ProcessEngine Configuration in Activiti](http://www.baeldung.com/activiti-process-engine) diff --git a/spring-activiti/pom.xml b/spring-activiti/pom.xml index c5289b20a6..92d9618b65 100644 --- a/spring-activiti/pom.xml +++ b/spring-activiti/pom.xml @@ -19,9 +19,11 @@ + com.example.activitiwithspring.ActivitiWithSpringApplication UTF-8 UTF-8 1.8 + 6.0.0 @@ -30,9 +32,14 @@ activiti-spring-boot-starter-basic 6.0.0 + + org.activiti + activiti-spring-boot-starter-security + ${activiti.version} + org.springframework.boot - spring-boot-starter-web + spring-boot-starter-thymeleaf @@ -67,7 +74,7 @@ **/JdbcTest.java **/*LiveTest.java - true + diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security.rar b/spring-activiti/src/main/java/com/baeldung/activiti/security.rar new file mode 100644 index 0000000000..38c4946168 Binary files /dev/null and b/spring-activiti/src/main/java/com/baeldung/activiti/security.rar differ diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/config/MvcConfig.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/MvcConfig.java new file mode 100644 index 0000000000..f9394742cd --- /dev/null +++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/MvcConfig.java @@ -0,0 +1,20 @@ +package com.baeldung.activiti.security.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +@Configuration +@EnableWebMvc +public class MvcConfig extends WebMvcConfigurerAdapter { + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/login") + .setViewName("login"); + registry.addViewController("/homepage") + .setViewName("homepage"); + } + +} diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/config/ProcessController.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/ProcessController.java new file mode 100644 index 0000000000..671b246328 --- /dev/null +++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/ProcessController.java @@ -0,0 +1,54 @@ +package com.baeldung.activiti.security.config; + +import java.util.List; + +import org.activiti.engine.IdentityService; +import org.activiti.engine.RuntimeService; +import org.activiti.engine.TaskService; +import org.activiti.engine.runtime.ProcessInstance; +import org.activiti.engine.task.Task; +import org.activiti.spring.SpringProcessEngineConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ProcessController { + + @Autowired + private RuntimeService runtimeService; + + @Autowired + private TaskService taskService; + + @Autowired + private IdentityService identityService; + + @Autowired + SpringProcessEngineConfiguration config; + + @GetMapping("/protected-process") + public String startProcess() { + + String userId = SecurityContextHolder.getContext() + .getAuthentication() + .getName(); + + identityService.setAuthenticatedUserId(userId); + + ProcessInstance pi = runtimeService.startProcessInstanceByKey("protected-process"); + + List usertasks = taskService.createTaskQuery() + .processInstanceId(pi.getId()) + .list(); + + taskService.complete(usertasks.iterator() + .next() + .getId()); + + return "Process started. Number of currently running process instances = " + runtimeService.createProcessInstanceQuery() + .count(); + } + +} diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityGroupManager.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityGroupManager.java new file mode 100644 index 0000000000..00fc674e22 --- /dev/null +++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityGroupManager.java @@ -0,0 +1,86 @@ +package com.baeldung.activiti.security.config; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.activiti.engine.identity.Group; +import org.activiti.engine.identity.GroupQuery; +import org.activiti.engine.impl.GroupQueryImpl; +import org.activiti.engine.impl.Page; +import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.activiti.engine.impl.persistence.entity.GroupEntityImpl; +import org.activiti.engine.impl.persistence.entity.GroupEntityManagerImpl; +import org.activiti.engine.impl.persistence.entity.data.GroupDataManager; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.provisioning.JdbcUserDetailsManager; + +public class SpringSecurityGroupManager extends GroupEntityManagerImpl { + + private JdbcUserDetailsManager userManager; + + public SpringSecurityGroupManager(ProcessEngineConfigurationImpl processEngineConfiguration, GroupDataManager groupDataManager) { + super(processEngineConfiguration, groupDataManager); + } + + @Override + public List findGroupByQueryCriteria(GroupQueryImpl query, Page page) { + + if (query.getUserId() != null) { + return findGroupsByUser(query.getUserId()); + } + return null; + } + + @Override + public long findGroupCountByQueryCriteria(GroupQueryImpl query) { + return findGroupByQueryCriteria(query, null).size(); + } + + @Override + public List findGroupsByUser(String userId) { + UserDetails userDetails = userManager.loadUserByUsername(userId); + System.out.println("group manager"); + if (userDetails != null) { + List groups = userDetails.getAuthorities() + .stream() + .map(a -> a.getAuthority()) + .map(a -> { + Group g = new GroupEntityImpl(); + g.setId(a); + return g; + }) + .collect(Collectors.toList()); + return groups; + } + return null; + } + + public void setUserManager(JdbcUserDetailsManager userManager) { + this.userManager = userManager; + } + + public Group createNewGroup(String groupId) { + throw new UnsupportedOperationException("This operation is not supported!"); + + } + + @Override + public void delete(String groupId) { + throw new UnsupportedOperationException("This operation is not supported!"); + + } + + public GroupQuery createNewGroupQuery() { + throw new UnsupportedOperationException("This operation is not supported!"); + } + + public List findGroupsByNativeQuery(Map parameterMap, int firstResult, int maxResults) { + throw new UnsupportedOperationException("This operation is not supported!"); + } + + public long findGroupCountByNativeQuery(Map parameterMap) { + throw new UnsupportedOperationException("This operation is not supported!"); + } + +} diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityUserManager.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityUserManager.java new file mode 100644 index 0000000000..ce9863eb6c --- /dev/null +++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/config/SpringSecurityUserManager.java @@ -0,0 +1,144 @@ +package com.baeldung.activiti.security.config; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.activiti.engine.identity.Group; +import org.activiti.engine.identity.User; +import org.activiti.engine.identity.UserQuery; +import org.activiti.engine.impl.Page; +import org.activiti.engine.impl.UserQueryImpl; +import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.activiti.engine.impl.persistence.entity.GroupEntityImpl; +import org.activiti.engine.impl.persistence.entity.UserEntity; +import org.activiti.engine.impl.persistence.entity.UserEntityImpl; +import org.activiti.engine.impl.persistence.entity.UserEntityManagerImpl; +import org.activiti.engine.impl.persistence.entity.data.UserDataManager; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.provisioning.JdbcUserDetailsManager; + +public class SpringSecurityUserManager extends UserEntityManagerImpl { + + private JdbcUserDetailsManager userManager; + + public SpringSecurityUserManager(ProcessEngineConfigurationImpl processEngineConfiguration, UserDataManager userDataManager, JdbcUserDetailsManager userManager) { + super(processEngineConfiguration, userDataManager); + this.userManager = userManager; + } + + @Override + public UserEntity findById(String userId) { + UserDetails userDetails = userManager.loadUserByUsername(userId); + if (userDetails != null) { + UserEntityImpl user = new UserEntityImpl(); + user.setId(userId); + return user; + } + return null; + + } + + @Override + public List findUserByQueryCriteria(UserQueryImpl query, Page page) { + List users = null; + if (query.getGroupId() != null) { + users = userManager.findUsersInGroup(query.getGroupId()) + .stream() + .map(username -> { + User user = new UserEntityImpl(); + user.setId(username); + return user; + }) + .collect(Collectors.toList()); + if (page != null) { + return users.subList(page.getFirstResult(), page.getFirstResult() + page.getMaxResults()); + + } + return users; + } + + if (query.getId() != null) { + UserDetails userDetails = userManager.loadUserByUsername(query.getId()); + if (userDetails != null) { + UserEntityImpl user = new UserEntityImpl(); + user.setId(query.getId()); + return Collections.singletonList(user); + } + } + return null; + } + + @Override + public Boolean checkPassword(String userId, String password) { + return true; + } + + public void setUserManager(JdbcUserDetailsManager userManager) { + this.userManager = userManager; + } + + public User createNewUser(String userId) { + throw new UnsupportedOperationException("This operation is not supported!"); + } + + public void updateUser(User updatedUser) { + throw new UnsupportedOperationException("This operation is not supported!"); + + } + + public void delete(UserEntity userEntity) { + throw new UnsupportedOperationException("This operation is not supported!"); + + } + + @Override + public void deletePicture(User user) { + UserEntity userEntity = (UserEntity) user; + if (userEntity.getPictureByteArrayRef() != null) { + userEntity.getPictureByteArrayRef() + .delete(); + } + } + + public void delete(String userId) { + throw new UnsupportedOperationException("This operation is not supported!"); + + } + + public long findUserCountByQueryCriteria(UserQueryImpl query) { + return findUserByQueryCriteria(query, null).size(); + } + + public List findGroupsByUser(String userId) { + UserDetails userDetails = userManager.loadUserByUsername(userId); + if (userDetails != null) { + List groups = userDetails.getAuthorities() + .stream() + .map(a -> a.getAuthority()) + .map(a -> { + Group g = new GroupEntityImpl(); + g.setId(a); + return g; + }) + .collect(Collectors.toList()); + return groups; + } + return null; + } + + public UserQuery createNewUserQuery() { + throw new UnsupportedOperationException("This operation is not supported!"); + } + + public List findUsersByNativeQuery(Map parameterMap, int firstResult, int maxResults) { + throw new UnsupportedOperationException("This operation is not supported!"); + } + + public long findUserCountByNativeQuery(Map parameterMap) { + throw new UnsupportedOperationException("This operation is not supported!"); + + } + +} diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SecurityConfig.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SecurityConfig.java new file mode 100644 index 0000000000..f471600553 --- /dev/null +++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SecurityConfig.java @@ -0,0 +1,47 @@ +package com.baeldung.activiti.security.withactiviti; + +import org.activiti.engine.IdentityService; +import org.activiti.spring.security.IdentityServiceUserDetailsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + protected void configure(HttpSecurity http) throws Exception { + http.antMatcher("/**") + .authorizeRequests() + .antMatchers("/protected-process*") + .authenticated() + .anyRequest() + .permitAll() + .and() + .formLogin() + .loginPage("/login") + .defaultSuccessUrl("/homepage") + .failureUrl("/login?error=true") + .and() + .csrf() + .disable() + .logout() + .logoutSuccessUrl("/login"); + } + + @Autowired + private IdentityService identityService; + + @Bean + public IdentityServiceUserDetailsService userDetailsService() { + return new IdentityServiceUserDetailsService(identityService); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService()); + } + +} diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SpringSecurityActivitiApplication.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SpringSecurityActivitiApplication.java new file mode 100644 index 0000000000..2270a4d684 --- /dev/null +++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/withactiviti/SpringSecurityActivitiApplication.java @@ -0,0 +1,34 @@ +package com.baeldung.activiti.security.withactiviti; + +import org.activiti.engine.IdentityService; +import org.activiti.engine.identity.Group; +import org.activiti.engine.identity.User; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication(scanBasePackages = { "com.baeldung.activiti.security.config", "com.baeldung.activiti.security.withactiviti" }) +public class SpringSecurityActivitiApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringSecurityActivitiApplication.class, args); + } + + @Bean + InitializingBean usersAndGroupsInitializer(IdentityService identityService) { + return new InitializingBean() { + public void afterPropertiesSet() throws Exception { + User user = identityService.newUser("activiti_user"); + user.setPassword("pass"); + identityService.saveUser(user); + + Group group = identityService.newGroup("user"); + group.setName("ROLE_USER"); + group.setType("USER"); + identityService.saveGroup(group); + identityService.createMembership(user.getId(), group.getId()); + } + }; + } +} diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/ActivitiSpringSecurityApplication.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/ActivitiSpringSecurityApplication.java new file mode 100644 index 0000000000..5878a5d678 --- /dev/null +++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/ActivitiSpringSecurityApplication.java @@ -0,0 +1,39 @@ +package com.baeldung.activiti.security.withspring; + +import org.activiti.engine.impl.persistence.entity.data.impl.MybatisGroupDataManager; +import org.activiti.engine.impl.persistence.entity.data.impl.MybatisUserDataManager; +import org.activiti.spring.SpringProcessEngineConfiguration; +import org.activiti.spring.boot.SecurityAutoConfiguration; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.security.provisioning.JdbcUserDetailsManager; + +import com.baeldung.activiti.security.config.SpringSecurityGroupManager; +import com.baeldung.activiti.security.config.SpringSecurityUserManager; + +@SpringBootApplication(exclude = SecurityAutoConfiguration.class, scanBasePackages = { "com.baeldung.activiti.security.config", "com.baeldung.activiti.security.withspring" }) +public class ActivitiSpringSecurityApplication { + + public static void main(String[] args) { + SpringApplication.run(ActivitiSpringSecurityApplication.class, args); + } + + @Autowired + private SpringProcessEngineConfiguration processEngineConfiguration; + + @Autowired + private JdbcUserDetailsManager userManager; + + @Bean + InitializingBean processEngineInitializer() { + return new InitializingBean() { + public void afterPropertiesSet() throws Exception { + processEngineConfiguration.setUserEntityManager(new SpringSecurityUserManager(processEngineConfiguration, new MybatisUserDataManager(processEngineConfiguration), userManager)); + processEngineConfiguration.setGroupEntityManager(new SpringSecurityGroupManager(processEngineConfiguration, new MybatisGroupDataManager(processEngineConfiguration))); + } + }; + } +} diff --git a/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/SecurityConfig.java b/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/SecurityConfig.java new file mode 100644 index 0000000000..df1991c3e4 --- /dev/null +++ b/spring-activiti/src/main/java/com/baeldung/activiti/security/withspring/SecurityConfig.java @@ -0,0 +1,50 @@ +package com.baeldung.activiti.security.withspring; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.provisioning.JdbcUserDetailsManager; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private DataSource dataSource; + + protected void configure(HttpSecurity http) throws Exception { + http.antMatcher("/**") + .authorizeRequests() + .antMatchers("/protected-process*") + .authenticated() + .anyRequest() + .permitAll() + .and() + .formLogin() + .loginPage("/login") + .defaultSuccessUrl("/homepage") + .failureUrl("/login?error=true") + .and() + .csrf() + .disable() + .logout() + .logoutSuccessUrl("/login"); + } + + @Bean + public JdbcUserDetailsManager userDetailsManager() { + JdbcUserDetailsManager manager = new JdbcUserDetailsManager(); + manager.setDataSource(dataSource); + return manager; + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsManager()); + } + +} diff --git a/spring-activiti/src/main/resources/data.sql b/spring-activiti/src/main/resources/data.sql new file mode 100644 index 0000000000..cb9b72617a --- /dev/null +++ b/spring-activiti/src/main/resources/data.sql @@ -0,0 +1,3 @@ +insert into users(username, password, enabled) values ('spring_user', 'pass', true); + +insert into authorities(username, authority) values ('spring_user','ROLE_USER'); \ No newline at end of file diff --git a/spring-activiti/src/main/resources/processes/protected-process.bpmn20.xml b/spring-activiti/src/main/resources/processes/protected-process.bpmn20.xml new file mode 100644 index 0000000000..b7e04515cd --- /dev/null +++ b/spring-activiti/src/main/resources/processes/protected-process.bpmn20.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + ROLE_USER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-activiti/src/main/resources/schema.sql b/spring-activiti/src/main/resources/schema.sql new file mode 100644 index 0000000000..bf882895fd --- /dev/null +++ b/spring-activiti/src/main/resources/schema.sql @@ -0,0 +1,3 @@ +create table users(username varchar(255), password varchar(255), enabled boolean); + +create table authorities(username varchar(255),authority varchar(255)); \ No newline at end of file diff --git a/spring-activiti/src/main/resources/templates/login.html b/spring-activiti/src/main/resources/templates/login.html new file mode 100644 index 0000000000..53077fd5f3 --- /dev/null +++ b/spring-activiti/src/main/resources/templates/login.html @@ -0,0 +1,21 @@ + + + +

    Login

    +
    + + + + + + + + + + + + +
    User:
    Password:
    +
    + + \ No newline at end of file diff --git a/spring-activiti/src/test/java/com/example/activitiwithspring/ActivitiSpringSecurityIntegrationTest.java b/spring-activiti/src/test/java/com/example/activitiwithspring/ActivitiSpringSecurityIntegrationTest.java new file mode 100644 index 0000000000..c2eeb96555 --- /dev/null +++ b/spring-activiti/src/test/java/com/example/activitiwithspring/ActivitiSpringSecurityIntegrationTest.java @@ -0,0 +1,31 @@ +package com.example.activitiwithspring; + +import org.activiti.engine.IdentityService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import com.baeldung.activiti.security.withspring.ActivitiSpringSecurityApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ActivitiSpringSecurityApplication.class) +@WebAppConfiguration +public class ActivitiSpringSecurityIntegrationTest { + @Autowired + private IdentityService identityService; + + @Test + public void whenUserExists_thenOk() { + identityService.setUserPicture("spring_user", null); + } + + @Test(expected = UsernameNotFoundException.class) + public void whenUserNonExistent_thenSpringException() { + identityService.setUserPicture("user3", null); + } + +} diff --git a/spring-all/README.md b/spring-all/README.md index 29be01c79e..e1504a66db 100644 --- a/spring-all/README.md +++ b/spring-all/README.md @@ -9,7 +9,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant articles: - [Guide to Spring @Autowired](http://www.baeldung.com/spring-autowire) -- [Properties with Spring](http://www.baeldung.com/2012/02/06/properties-with-spring) - checkout the `org.baeldung.properties` package for all scenarios of properties injection and usage +- [Properties with Spring](http://www.baeldung.com/properties-with-spring) - checkout the `org.baeldung.properties` package for all scenarios of properties injection and usage - [Spring Profiles](http://www.baeldung.com/spring-profiles) - [A Spring Custom Annotation for a Better DAO](http://www.baeldung.com/spring-annotation-bean-pre-processor) - [What's New in Spring 4.3?](http://www.baeldung.com/whats-new-in-spring-4-3/) @@ -23,3 +23,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [New in Guava 21 common.util.concurrent](http://www.baeldung.com/guava-21-util-concurrent) - [A CLI with Spring Shell](http://www.baeldung.com/spring-shell-cli) - [JasperReports with Spring](http://www.baeldung.com/spring-jasper) +- [Model, ModelMap, and ModelView in Spring MVC](http://www.baeldung.com/spring-mvc-model-model-map-model-view) diff --git a/spring-all/pom.xml b/spring-all/pom.xml index 1ecb824c40..6615e1d6cd 100644 --- a/spring-all/pom.xml +++ b/spring-all/pom.xml @@ -195,7 +195,11 @@ spring-core ${org.springframework.version} - + + + org.springframework.boot + spring-boot-starter-thymeleaf + @@ -280,4 +284,4 @@ - \ No newline at end of file + diff --git a/spring-all/src/main/java/org/baeldung/controller/controller/PassParametersController.java b/spring-all/src/main/java/org/baeldung/controller/controller/PassParametersController.java new file mode 100644 index 0000000000..c282ae6a62 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/controller/controller/PassParametersController.java @@ -0,0 +1,37 @@ +package org.baeldung.controller.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.ModelAndView; + +/** + * In this controller, Model, ModelMap and ModelAndView are shown as examples. + * They are all used to pass parameters to JSP pages. + * 04/09/2017 + * + * @author Ahmet Cetin + */ +@Controller +public class PassParametersController { + @GetMapping("/showViewPage") + public String passParametersWithModel(Model model) { + model.addAttribute("message", "Baeldung"); + return "viewPage"; + } + + @GetMapping("/printViewPage") + public String passParametersWithModelMap(ModelMap map) { + map.addAttribute("welcomeMessage", "welcome"); + map.addAttribute("message", "Baeldung"); + return "viewPage"; + } + + @GetMapping("/goToViewPage") + public ModelAndView passParametersWithModelAndView() { + ModelAndView modelAndView = new ModelAndView("viewPage"); + modelAndView.addObject("message", "Baeldung"); + return modelAndView; + } +} diff --git a/spring-all/src/main/webapp/WEB-INF/view/viewPage.html b/spring-all/src/main/webapp/WEB-INF/view/viewPage.html new file mode 100644 index 0000000000..71f766407e --- /dev/null +++ b/spring-all/src/main/webapp/WEB-INF/view/viewPage.html @@ -0,0 +1,9 @@ + + + + Title + + +
    Web Application. Passed parameter : th:text="${message}"
    + + diff --git a/spring-all/src/test/java/org/baeldung/controller/PassParametersControllerTest.java b/spring-all/src/test/java/org/baeldung/controller/PassParametersControllerTest.java new file mode 100644 index 0000000000..76ac14f292 --- /dev/null +++ b/spring-all/src/test/java/org/baeldung/controller/PassParametersControllerTest.java @@ -0,0 +1,69 @@ +package org.baeldung.controller; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.ModelAndView; + +/** + * This is the test class for {@link org.baeldung.controller.controller.PassParametersController} class. + * 09/09/2017 + * + * @author Ahmet Cetin + */ +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@ContextConfiguration({"classpath:test-mvc.xml"}) +public class PassParametersControllerTest { + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Before + public void setUp() { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); + } + + @Test + public void testPassParametersWithModel() throws Exception { + ModelAndView mv = this.mockMvc.perform(MockMvcRequestBuilders.get("/showViewPage")).andReturn().getModelAndView(); + + //Validate view + Assert.assertEquals(mv.getViewName(), "viewPage"); + + //Validate attribute + Assert.assertEquals(mv.getModelMap().get("message").toString(), "Baeldung"); + } + + @Test + public void testPassParametersWithModelMap() throws Exception { + ModelAndView mv = this.mockMvc.perform(MockMvcRequestBuilders.get("/printViewPage")).andReturn().getModelAndView(); + + //Validate view + Assert.assertEquals(mv.getViewName(), "viewPage"); + + //Validate attribute + Assert.assertEquals(mv.getModelMap().get("message").toString(), "Baeldung"); + } + + @Test + public void testPassParametersWithModelAndView() throws Exception { + ModelAndView mv = this.mockMvc.perform(MockMvcRequestBuilders.get("/goToViewPage")).andReturn().getModelAndView(); + + //Validate view + Assert.assertEquals(mv.getViewName(), "viewPage"); + + //Validate attribute + Assert.assertEquals(mv.getModelMap().get("message").toString(), "Baeldung"); + } +} diff --git a/spring-aop/src/main/java/org/baeldung/logger/AdderAfterAspect.java b/spring-aop/src/main/java/org/baeldung/logger/AdderAfterAspect.java new file mode 100644 index 0000000000..59afa38f06 --- /dev/null +++ b/spring-aop/src/main/java/org/baeldung/logger/AdderAfterAspect.java @@ -0,0 +1,13 @@ +package org.baeldung.logger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AdderAfterAspect { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public void afterAdvice() throws Throwable { + logger.info("I'm done calling the method"); + } +} diff --git a/spring-aop/src/main/java/org/baeldung/logger/AdderAfterReturnAspect.java b/spring-aop/src/main/java/org/baeldung/logger/AdderAfterReturnAspect.java new file mode 100644 index 0000000000..a2b1959374 --- /dev/null +++ b/spring-aop/src/main/java/org/baeldung/logger/AdderAfterReturnAspect.java @@ -0,0 +1,13 @@ +package org.baeldung.logger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AdderAfterReturnAspect { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public void afterReturn(final Object returnValue) throws Throwable { + logger.info("value return was {}", returnValue); + } +} diff --git a/spring-aop/src/main/java/org/baeldung/logger/AdderAfterThrowAspect.java b/spring-aop/src/main/java/org/baeldung/logger/AdderAfterThrowAspect.java new file mode 100644 index 0000000000..1f19af05e4 --- /dev/null +++ b/spring-aop/src/main/java/org/baeldung/logger/AdderAfterThrowAspect.java @@ -0,0 +1,13 @@ +package org.baeldung.logger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AdderAfterThrowAspect { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public void afterThrow(final Exception exception) throws Throwable { + logger.info("Exception thrown was {}", exception.getMessage()); + } +} diff --git a/spring-aop/src/main/java/org/baeldung/logger/AdderAroundAspect.java b/spring-aop/src/main/java/org/baeldung/logger/AdderAroundAspect.java new file mode 100644 index 0000000000..fceba87d15 --- /dev/null +++ b/spring-aop/src/main/java/org/baeldung/logger/AdderAroundAspect.java @@ -0,0 +1,18 @@ +package org.baeldung.logger; + +import java.util.Arrays; +import org.aspectj.lang.ProceedingJoinPoint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AdderAroundAspect { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public Object aroundAdvice(final ProceedingJoinPoint joinPoint) throws Throwable { + logger.info("Arguments passed to method are: " + Arrays.toString(joinPoint.getArgs())); + final Object result = joinPoint.proceed(); + logger.info("Result from method is: " + result); + return result; + } +} diff --git a/spring-aop/src/main/java/org/baeldung/logger/AdderBeforeAspect.java b/spring-aop/src/main/java/org/baeldung/logger/AdderBeforeAspect.java new file mode 100644 index 0000000000..750e7ba122 --- /dev/null +++ b/spring-aop/src/main/java/org/baeldung/logger/AdderBeforeAspect.java @@ -0,0 +1,13 @@ +package org.baeldung.logger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AdderBeforeAspect { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public void beforeAdvice() throws Throwable { + logger.info("I would be executed just before method starts"); + } +} diff --git a/spring-aop/src/main/java/org/baeldung/logger/SampleAdder.java b/spring-aop/src/main/java/org/baeldung/logger/SampleAdder.java new file mode 100644 index 0000000000..96fda1b0b9 --- /dev/null +++ b/spring-aop/src/main/java/org/baeldung/logger/SampleAdder.java @@ -0,0 +1,12 @@ +package org.baeldung.logger; + +public class SampleAdder { + + public int add(int a, int b) { + if (a < 0 || b < 0) { + throw new IllegalArgumentException("Make sure all the arguments are greater than zero."); + } + return a + b; + } + +} diff --git a/spring-aop/src/main/java/org/baeldung/performancemonitor/AopConfiguration.java b/spring-aop/src/main/java/org/baeldung/performancemonitor/AopConfiguration.java index a5f36fb716..00026baf07 100644 --- a/spring-aop/src/main/java/org/baeldung/performancemonitor/AopConfiguration.java +++ b/spring-aop/src/main/java/org/baeldung/performancemonitor/AopConfiguration.java @@ -16,10 +16,10 @@ import java.time.Month; @EnableAspectJAutoProxy public class AopConfiguration { - @Pointcut("execution(public String com.baeldung.performancemonitor.PersonService.getFullName(..))") + @Pointcut("execution(public String org.baeldung.performancemonitor.PersonService.getFullName(..))") public void monitor() { } - @Pointcut("execution(public int com.baeldung.performancemonitor.PersonService.getAge(..))") + @Pointcut("execution(public int org.baeldung.performancemonitor.PersonService.getAge(..))") public void myMonitor() { } @Bean @@ -30,7 +30,7 @@ public class AopConfiguration { @Bean public Advisor performanceMonitorAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); - pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.monitor()"); + pointcut.setExpression("org.baeldung.performancemonitor.AopConfiguration.monitor()"); return new DefaultPointcutAdvisor(pointcut, performanceMonitorInterceptor()); } @@ -52,7 +52,7 @@ public class AopConfiguration { @Bean public Advisor myPerformanceMonitorAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); - pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.myMonitor()"); + pointcut.setExpression("org.baeldung.performancemonitor.AopConfiguration.myMonitor()"); return new DefaultPointcutAdvisor(pointcut, myPerformanceMonitorInterceptor()); } diff --git a/spring-aop/src/main/resources/logback.xml b/spring-aop/src/main/resources/logback.xml index ec0dc2469a..3245e94f08 100644 --- a/spring-aop/src/main/resources/logback.xml +++ b/spring-aop/src/main/resources/logback.xml @@ -13,7 +13,11 @@ - + + + + + \ No newline at end of file diff --git a/spring-aop/src/main/resources/org.baeldung.logger/springAop-applicationContext.xml b/spring-aop/src/main/resources/org.baeldung.logger/springAop-applicationContext.xml new file mode 100644 index 0000000000..058beaa7a1 --- /dev/null +++ b/spring-aop/src/main/resources/org.baeldung.logger/springAop-applicationContext.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-aop/src/test/java/org/baeldung/logger/CalculatorTest.java b/spring-aop/src/test/java/org/baeldung/logger/CalculatorTest.java new file mode 100644 index 0000000000..b1c88c67df --- /dev/null +++ b/spring-aop/src/test/java/org/baeldung/logger/CalculatorTest.java @@ -0,0 +1,29 @@ +package org.baeldung.logger; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(value = {"classpath:springAop-applicationContext.xml"}) +public class CalculatorTest { + + @Autowired + private SampleAdder sampleAdder; + + @Test + public void whenAddValidValues_returnsSucessfully() { + final int addedValue = sampleAdder.add(12, 12); + + assertEquals(24, addedValue); + } + + @Test (expected = IllegalArgumentException.class) + public void whenAddInValidValues_throwsException() { + sampleAdder.add(12, -12); + } + +} diff --git a/spring-aop/src/test/resources/springAop-applicationContext.xml b/spring-aop/src/test/resources/springAop-applicationContext.xml new file mode 100644 index 0000000000..4d88bd3711 --- /dev/null +++ b/spring-aop/src/test/resources/springAop-applicationContext.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-batch/README.md b/spring-batch/README.md index 953e652cea..5f226e7fd7 100644 --- a/spring-batch/README.md +++ b/spring-batch/README.md @@ -5,3 +5,4 @@ ### Relevant Articles: - [Introduction to Spring Batch](http://www.baeldung.com/introduction-to-spring-batch) +- [Spring Batch using Partitioner](https://github.com/eugenp/tutorials/tree/master/spring-batch) diff --git a/spring-boot-actuator/.gitignore b/spring-boot-actuator/.gitignore new file mode 100644 index 0000000000..60be5b80aa --- /dev/null +++ b/spring-boot-actuator/.gitignore @@ -0,0 +1,4 @@ +/target/ +.settings/ +.classpath +.project diff --git a/spring-boot-actuator/README.MD b/spring-boot-actuator/README.MD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml new file mode 100644 index 0000000000..bec126a247 --- /dev/null +++ b/spring-boot-actuator/pom.xml @@ -0,0 +1,121 @@ + + 4.0.0 + com.baeldung + spring-boot-actuator + 0.0.1-SNAPSHOT + jar + spring-boot + This is simple boot application for Spring boot actuator test + + + + org.springframework.boot + spring-boot-starter-parent + 1.5.2.RELEASE + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + spring-boot-actuator + + + src/main/resources + true + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*IntegrationTest.java + + + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + + org.baeldung.MainApplication + UTF-8 + 1.8 + + + diff --git a/spring-boot-actuator/src/main/java/org/baeldung/MainApplication.java b/spring-boot-actuator/src/main/java/org/baeldung/MainApplication.java new file mode 100644 index 0000000000..7c9054dbf8 --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/baeldung/MainApplication.java @@ -0,0 +1,13 @@ +package org.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.baeldung.config.MainConfig; + +@SpringBootApplication +public class MainApplication { + + public static void main(String args[]) { + SpringApplication.run(MainConfig.class, args); + } +} diff --git a/spring-boot-actuator/src/main/java/org/baeldung/config/MainConfig.java b/spring-boot-actuator/src/main/java/org/baeldung/config/MainConfig.java new file mode 100644 index 0000000000..27c97cc006 --- /dev/null +++ b/spring-boot-actuator/src/main/java/org/baeldung/config/MainConfig.java @@ -0,0 +1,17 @@ +package org.baeldung.config; + +import java.util.Collections; +import org.springframework.boot.actuate.info.InfoContributor; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Bean; + +@EnableAutoConfiguration +public class MainConfig { + + public MainConfig() {} + + @Bean + public InfoContributor getInfoContributor() { + return (infoBuilder) -> infoBuilder.withDetail("applicationInfo", Collections.singletonMap("ActiveUserCount", "10")); + } +} diff --git a/spring-boot-actuator/src/main/resources/application.properties b/spring-boot-actuator/src/main/resources/application.properties new file mode 100644 index 0000000000..835c78eda2 --- /dev/null +++ b/spring-boot-actuator/src/main/resources/application.properties @@ -0,0 +1 @@ +info.app.name=Sample application \ No newline at end of file diff --git a/spring-boot-actuator/src/test/java/org/baeldung/config/ActuatorInfoIntegrationTest.java b/spring-boot-actuator/src/test/java/org/baeldung/config/ActuatorInfoIntegrationTest.java new file mode 100644 index 0000000000..0b5e3b3eef --- /dev/null +++ b/spring-boot-actuator/src/test/java/org/baeldung/config/ActuatorInfoIntegrationTest.java @@ -0,0 +1,32 @@ +package org.baeldung.config; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import static org.junit.Assert.*; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = MainConfig.class) +@TestPropertySource(properties = { "security.basic.enabled=false" }) +public class ActuatorInfoIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void whenGetInfo_thenAdditionalInfoReturned() throws IOException { + final String expectedResponse = new String(Files.readAllBytes(Paths.get("src/test/resources/expectedResponse.json"))); + final ResponseEntity responseEntity = this.restTemplate.getForEntity("/info", String.class); + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertEquals(expectedResponse, responseEntity.getBody()); + } +} \ No newline at end of file diff --git a/spring-boot-actuator/src/test/resources/expectedResponse.json b/spring-boot-actuator/src/test/resources/expectedResponse.json new file mode 100644 index 0000000000..caa0bdbbf8 --- /dev/null +++ b/spring-boot-actuator/src/test/resources/expectedResponse.json @@ -0,0 +1 @@ +{"app":{"name":"Sample application"},"applicationInfo":{"ActiveUserCount":"10"}} \ No newline at end of file diff --git a/spring-boot-admin/README.md b/spring-boot-admin/README.md new file mode 100644 index 0000000000..622533a6ad --- /dev/null +++ b/spring-boot-admin/README.md @@ -0,0 +1,17 @@ +## 1. Spring Boot Admin Server + +* mvn clean install +* mvn spring-boot:run +* starts on port 8080 +* login with admin/admin +* to activate mail notifications uncomment the starter mail dependency +and the mail configuration from application.properties +* add some real credentials if you want the app to send emails +* to activate Hipchat notifications proceed same as for email + +## 2. Spring Boot App Client + +* mvn clean install +* mvn spring-boot:run +* starts on port 8081 +* basic auth client/client \ No newline at end of file diff --git a/spring-boot-admin/pom.xml b/spring-boot-admin/pom.xml new file mode 100644 index 0000000000..9c1eeeabff --- /dev/null +++ b/spring-boot-admin/pom.xml @@ -0,0 +1,36 @@ + + 4.0.0 + spring-boot-admin + 0.0.1-SNAPSHOT + pom + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + UTF-8 + 1.5.8.RELEASE + + + + spring-boot-admin-server + spring-boot-admin-client + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-client/.gitignore b/spring-boot-admin/spring-boot-admin-client/.gitignore new file mode 100644 index 0000000000..2af7cefb0a --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/.gitignore @@ -0,0 +1,24 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-client/pom.xml b/spring-boot-admin/spring-boot-admin-client/pom.xml new file mode 100644 index 0000000000..d119450e0b --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + spring-boot-admin-client + 0.0.1-SNAPSHOT + jar + + spring-boot-admin-client + Spring Boot Admin Client + + + spring-boot-admin + com.baeldung + 0.0.1-SNAPSHOT + ../../spring-boot-admin + + + + UTF-8 + UTF-8 + 1.8 + 1.5.4 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-security + + + de.codecentric + spring-boot-admin-starter-client + ${spring-boot-admin-starter-client.version} + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + build-info + + + + + + + + + diff --git a/spring-boot-admin/spring-boot-admin-client/src/main/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplication.java b/spring-boot-admin/spring-boot-admin-client/src/main/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplication.java new file mode 100644 index 0000000000..596da131a6 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/src/main/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.springbootadminclient; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootAdminClientApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootAdminClientApplication.class, args); + } +} diff --git a/spring-boot-admin/spring-boot-admin-client/src/main/resources/application.properties b/spring-boot-admin/spring-boot-admin-client/src/main/resources/application.properties new file mode 100644 index 0000000000..58c178ecd9 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/src/main/resources/application.properties @@ -0,0 +1,16 @@ +#basic auth creddentials +security.user.name=client +security.user.password=client + +#configs to connect to a secured server +spring.boot.admin.url=http://localhost:8080 +spring.boot.admin.username=admin +spring.boot.admin.password=admin + +#configs to give secured server info +spring.boot.admin.client.metadata.user.name=${security.user.name} +spring.boot.admin.client.metadata.user.password=${security.user.password} + +#app config +spring.application.name=spring-boot-admin-client +server.port=8081 \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-client/src/main/resources/logback.xml b/spring-boot-admin/spring-boot-admin-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..ff96acae79 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + + %date [%thread] %-5level %logger{25} - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationIntegrationTest.java b/spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationIntegrationTest.java new file mode 100644 index 0000000000..0201deabca --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationIntegrationTest.java @@ -0,0 +1,55 @@ +package com.baeldung.springbootadminclient; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.env.Environment; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.junit.Assert.assertEquals; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = RANDOM_PORT) +public class SpringBootAdminClientApplicationIntegrationTest { + + @Autowired Environment environment; + + @Autowired WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() { + mockMvc = MockMvcBuilders + .webAppContextSetup(wac) + .build(); + } + + @Test + public void whenEnvironmentAvailable_ThenAdminServerPropertiesExist() { + assertEquals(environment.getProperty("spring.boot.admin.url"), "http://localhost:8080"); + assertEquals(environment.getProperty("spring.boot.admin.username"), "admin"); + assertEquals(environment.getProperty("spring.boot.admin.password"), "admin"); + } + + @Test + public void whenHttpBasicAttempted_ThenSuccess() throws Exception { + mockMvc.perform(get("/env").with(httpBasic("client", "client"))); + } + + @Test + public void whenInvalidHttpBasicAttempted_ThenUnauthorized() throws Exception { + mockMvc + .perform(get("/env").with(httpBasic("client", "invalid"))) + .andExpect(status().isUnauthorized()); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/.gitignore b/spring-boot-admin/spring-boot-admin-server/.gitignore new file mode 100644 index 0000000000..2af7cefb0a --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/.gitignore @@ -0,0 +1,24 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-server/pom.xml b/spring-boot-admin/spring-boot-admin-server/pom.xml new file mode 100644 index 0000000000..f28b7a3dc9 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + spring-boot-admin-server + 0.0.1-SNAPSHOT + jar + + spring-boot-admin-server + Spring Boot Admin Server + + + spring-boot-admin + com.baeldung + 0.0.1-SNAPSHOT + ../../spring-boot-admin + + + + UTF-8 + UTF-8 + 1.8 + 1.5.4 + 1.5.4 + + + + + org.springframework.boot + spring-boot-starter + + + + + de.codecentric + spring-boot-admin-server + ${spring-boot-admin-server.version} + + + de.codecentric + spring-boot-admin-server-ui + ${spring-boot-admin-server.version} + + + + + de.codecentric + spring-boot-admin-server-ui-login + ${spring-boot-admin-server.version} + + + org.springframework.boot + spring-boot-starter-security + + + com.hazelcast + hazelcast + + + + de.codecentric + spring-boot-admin-starter-client + ${spring-boot-admin-starter-client.version} + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/SpringBootAdminServerApplication.java b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/SpringBootAdminServerApplication.java new file mode 100644 index 0000000000..d1fb4e769b --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/SpringBootAdminServerApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.springbootadminserver; + +import de.codecentric.boot.admin.config.EnableAdminServer; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@EnableAdminServer +@SpringBootApplication +public class SpringBootAdminServerApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootAdminServerApplication.class, args); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/HazelcastConfig.java b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/HazelcastConfig.java new file mode 100644 index 0000000000..b19b7820af --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/HazelcastConfig.java @@ -0,0 +1,24 @@ +package com.baeldung.springbootadminserver.configs; + +import com.hazelcast.config.Config; +import com.hazelcast.config.EvictionPolicy; +import com.hazelcast.config.ListConfig; +import com.hazelcast.config.MapConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class HazelcastConfig { + + @Bean + public Config hazelcast() { + return new Config() + .setProperty("hazelcast.jmx", "true") + .addMapConfig(new MapConfig("spring-boot-admin-application-store") + .setBackupCount(1) + .setEvictionPolicy(EvictionPolicy.NONE)) + .addListConfig(new ListConfig("spring-boot-admin-event-store") + .setBackupCount(1) + .setMaxSize(1000)); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/NotifierConfiguration.java b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/NotifierConfiguration.java new file mode 100644 index 0000000000..10a31464ab --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/NotifierConfiguration.java @@ -0,0 +1,42 @@ +package com.baeldung.springbootadminserver.configs; + +import de.codecentric.boot.admin.notify.LoggingNotifier; +import de.codecentric.boot.admin.notify.RemindingNotifier; +import de.codecentric.boot.admin.notify.filter.FilteringNotifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.concurrent.TimeUnit; + +@Configuration +@EnableScheduling +public class NotifierConfiguration { + + // @Autowired private Notifier notifier; + + @Bean + public LoggingNotifier notifier() { + return new LoggingNotifier(); + } + + @Bean + public FilteringNotifier filteringNotifier() { + return new FilteringNotifier(notifier()); + } + + @Bean + @Primary + public RemindingNotifier remindingNotifier() { + RemindingNotifier remindingNotifier = new RemindingNotifier(filteringNotifier()); + remindingNotifier.setReminderPeriod(TimeUnit.MINUTES.toMillis(5)); + return remindingNotifier; + } + + @Scheduled(fixedRate = 60_000L) + public void remind() { + remindingNotifier().sendReminders(); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/WebSecurityConfig.java b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/WebSecurityConfig.java new file mode 100644 index 0000000000..4a7c8330b7 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/WebSecurityConfig.java @@ -0,0 +1,33 @@ +package com.baeldung.springbootadminserver.configs; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .formLogin() + .loginPage("/login.html") + .loginProcessingUrl("/login") + .permitAll(); + http + .logout() + .logoutUrl("/logout"); + http + .csrf() + .disable(); + http + .authorizeRequests() + .antMatchers("/login.html", "/**/*.css", "/img/**", "/third-party/**") + .permitAll(); + http + .authorizeRequests() + .antMatchers("/**") + .authenticated(); + http.httpBasic(); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/resources/application.properties b/spring-boot-admin/spring-boot-admin-server/src/main/resources/application.properties new file mode 100644 index 0000000000..362f6428e8 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/resources/application.properties @@ -0,0 +1,28 @@ +spring.application.name=spring-boot-admin-server + +security.user.name=admin +security.user.password=admin + +#configs to connect to self register the admin server as a client +spring.boot.admin.url=http://localhost:8080 +spring.boot.admin.username=${security.user.name} +spring.boot.admin.password=${security.user.password} + +#configs to give secured server info +spring.boot.admin.client.metadata.user.name=${security.user.name} +spring.boot.admin.client.metadata.user.password=${security.user.password} + +#mail notifications +#spring.mail.host=smtp.gmail.com +#spring.mail.username=test@gmail.com +#spring.mail.password=password +#spring.mail.port=587 +#spring.mail.properties.mail.smtp.auth=true +#spring.mail.properties.mail.smtp.starttls.enable=true + +#spring.boot.admin.notify.mail.to=test@gmail.com + +#hipchat notifications +#spring.boot.admin.notify.hipchat.auth-token= +#spring.boot.admin.notify.hipchat.room-id= +#spring.boot.admin.notify.hipchat.url=https://youcompany.hipchat.com/v2/ \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/resources/logback.xml b/spring-boot-admin/spring-boot-admin-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..ff96acae79 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + + %date [%thread] %-5level %logger{25} - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigIntegrationTest.java b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigIntegrationTest.java new file mode 100644 index 0000000000..7c1b1881a4 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigIntegrationTest.java @@ -0,0 +1,24 @@ +package com.baeldung.springbootadminserver; + +import com.baeldung.springbootadminserver.configs.HazelcastConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.assertNotEquals; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { HazelcastConfig.class }, webEnvironment = NONE) +public class HazelcastConfigIntegrationTest { + + @Autowired private ApplicationContext applicationContext; + + @Test + public void whenApplicationContextStarts_HazelcastConfigBeanExists() { + assertNotEquals(applicationContext.getBean("hazelcast"), null); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationIntegrationTest.java b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationIntegrationTest.java new file mode 100644 index 0000000000..465d079ac3 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationIntegrationTest.java @@ -0,0 +1,41 @@ +package com.baeldung.springbootadminserver; + +import com.baeldung.springbootadminserver.configs.NotifierConfiguration; +import de.codecentric.boot.admin.notify.Notifier; +import de.codecentric.boot.admin.notify.RemindingNotifier; +import de.codecentric.boot.admin.notify.filter.FilteringNotifier; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.assertNotEquals; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { NotifierConfiguration.class }, webEnvironment = NONE) +public class NotifierConfigurationIntegrationTest { + + @Autowired private ApplicationContext applicationContext; + + @Test + public void whenApplicationContextStart_ThenNotifierBeanExists() { + Notifier notifier = (Notifier) applicationContext.getBean("notifier"); + assertNotEquals(notifier, null); + } + + @Test + public void whenApplicationContextStart_ThenFilteringNotifierBeanExists() { + FilteringNotifier filteringNotifier = (FilteringNotifier) applicationContext.getBean("filteringNotifier"); + assertNotEquals(filteringNotifier, null); + } + + @Test + public void whenApplicationContextStart_ThenRemindingNotifierBeanExists() { + RemindingNotifier remindingNotifier = (RemindingNotifier) applicationContext.getBean("remindingNotifier"); + assertNotEquals(remindingNotifier, null); + } + +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigIntegrationTest.java b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigIntegrationTest.java new file mode 100644 index 0000000000..0c0695e6c2 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigIntegrationTest.java @@ -0,0 +1,71 @@ +package com.baeldung.springbootadminserver; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class WebSecurityConfigIntegrationTest { + + @Autowired WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() { + mockMvc = MockMvcBuilders + .webAppContextSetup(wac) + .build(); + } + + @Test + public void whenApplicationStarts_ThenGetLoginPageWithSuccess() throws Exception { + mockMvc + .perform(get("/login.html")) + .andExpect(status().is2xxSuccessful()); + } + + @Test + public void whenFormLoginAttempted_ThenSuccess() throws Exception { + mockMvc.perform(formLogin("/login") + .user("admin") + .password("admin")); + } + + @Test + public void whenFormLoginWithSuccess_ThenApiEndpointsAreAccessible() throws Exception { + mockMvc.perform(formLogin("/login") + .user("admin") + .password("admin")); + + mockMvc + .perform(get("/api/applications/")) + .andExpect(status().is2xxSuccessful()); + + } + + @Test + public void whenHttpBasicAttempted_ThenSuccess() throws Exception { + mockMvc.perform(get("/env").with(httpBasic("admin", "admin"))); + } + + @Test + public void whenInvalidHttpBasicAttempted_ThenUnauthorized() throws Exception { + mockMvc + .perform(get("/env").with(httpBasic("admin", "invalid"))) + .andExpect(status().isUnauthorized()); + } + +} diff --git a/spring-boot-bootstrap/README.md b/spring-boot-bootstrap/README.md index 75a2b35be7..ec6905bf6a 100644 --- a/spring-boot-bootstrap/README.md +++ b/spring-boot-bootstrap/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [Bootstrap a Simple Application using Spring Boot](http://www.baeldung.com/spring-boot-start) +- [Spring Boot Dependency Management with a Custom Parent](http://www.baeldung.com/spring-boot-dependency-management-custom-parent) diff --git a/spring-boot-bootstrap/pom.xml b/spring-boot-bootstrap/pom.xml index 9da37a3261..5ad8330a89 100644 --- a/spring-boot-bootstrap/pom.xml +++ b/spring-boot-bootstrap/pom.xml @@ -12,10 +12,10 @@ Demo project for Spring Boot - org.springframework.boot - spring-boot-starter-parent - 1.5.3.RELEASE - + parent-boot-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-5 + + diff --git a/spring-boot-keycloak/src/main/resources/templates/external.html b/spring-boot-keycloak/src/main/resources/templates/external.html new file mode 100644 index 0000000000..2f9cc76961 --- /dev/null +++ b/spring-boot-keycloak/src/main/resources/templates/external.html @@ -0,0 +1,31 @@ + + + + + +
    + + + + diff --git a/spring-boot-keycloak/src/main/resources/templates/layout.html b/spring-boot-keycloak/src/main/resources/templates/layout.html new file mode 100644 index 0000000000..bab0c2982b --- /dev/null +++ b/spring-boot-keycloak/src/main/resources/templates/layout.html @@ -0,0 +1,18 @@ + + + +Customer Portal + + + + + \ No newline at end of file diff --git a/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java b/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java new file mode 100644 index 0000000000..e0bbef1c7f --- /dev/null +++ b/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java @@ -0,0 +1,50 @@ +package com.baeldung.keycloak; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.keycloak.KeycloakPrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.springboot.client.KeycloakSecurityContextClientRequestInterceptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = SpringBoot.class) +public class KeycloakConfigurationIntegrationTest { + + @Spy + private KeycloakSecurityContextClientRequestInterceptor factory; + + private MockHttpServletRequest servletRequest; + + @Mock + public KeycloakSecurityContext keycloakSecurityContext; + + @Mock + private KeycloakPrincipal keycloakPrincipal; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + servletRequest = new MockHttpServletRequest(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(servletRequest)); + servletRequest.setUserPrincipal(keycloakPrincipal); + when(keycloakPrincipal.getKeycloakSecurityContext()).thenReturn(keycloakSecurityContext); + } + + @Test + public void testGetKeycloakSecurityContext() throws Exception { + assertNotNull(keycloakPrincipal.getKeycloakSecurityContext()); + } + +} diff --git a/spring-boot-property-exp/README.md b/spring-boot-property-exp/README.md index 8a598e7a05..70cf6bdfac 100644 --- a/spring-boot-property-exp/README.md +++ b/spring-boot-property-exp/README.md @@ -1,5 +1,5 @@ ## The Module Holds Sources for the Following Articles - - [Automatic Property Expansion with Spring Boot](http://www.baeldung.com/property-expansion-spring-boot) + - [Automatic Property Expansion with Spring Boot](http://www.baeldung.com/spring-boot-auto-property-expansion) ### Module property-exp-default-config This module contains both a standard Maven Spring Boot build and the Gradle build which is Maven compatible. @@ -15,4 +15,4 @@ ### Module property-exp-custom-config This project is not using the standard Spring Boot parent and is configured manually. Run the following command: - `mvn exec:java` \ No newline at end of file + `mvn exec:java` diff --git a/spring-boot/.factorypath b/spring-boot/.factorypath new file mode 100644 index 0000000000..aa15485f5c --- /dev/null +++ b/spring-boot/.factorypath @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-boot/.gitignore b/spring-boot/.gitignore index e26d6af438..88e3308e9d 100644 --- a/spring-boot/.gitignore +++ b/spring-boot/.gitignore @@ -2,3 +2,4 @@ .settings/ .classpath .project + diff --git a/spring-boot/README.MD b/spring-boot/README.MD index e837c88804..f126df00af 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -26,4 +26,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [How to Get All Spring-Managed Beans?](http://www.baeldung.com/spring-show-all-beans) - [A Java Client for a WebSockets API](http://www.baeldung.com/websockets-api-java-spring-client) - [Spring Boot and Togglz Aspect](http://www.baeldung.com/spring-togglz) +- [Getting Started with GraphQL and Spring Boot](http://www.baeldung.com/spring-graphql) +- [Guide to Spring Type Conversions](http://www.baeldung.com/spring-type-conversions) diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index 9d44de64a3..d6ee022522 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -24,7 +24,6 @@ org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-data-jpa @@ -73,7 +72,6 @@ tomcat-embed-core ${tomcat.version} - org.apache.tomcat.embed tomcat-embed-jasper @@ -269,7 +267,7 @@ - org.baeldung.boot.DemoApplication + org.baeldung.demo.DemoApplication 4.3.4.RELEASE 2.2.1 3.1.1 @@ -280,4 +278,4 @@ 2.4.1.Final - + \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/Application.java b/spring-boot/src/main/java/org/baeldung/boot/Application.java similarity index 95% rename from spring-boot/src/main/java/org/baeldung/Application.java rename to spring-boot/src/main/java/org/baeldung/boot/Application.java index 1c1e466afc..78e95455b8 100644 --- a/spring-boot/src/main/java/org/baeldung/Application.java +++ b/spring-boot/src/main/java/org/baeldung/boot/Application.java @@ -1,4 +1,4 @@ -package org.baeldung; +package org.baeldung.boot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-boot/src/main/java/org/baeldung/client/Details.java b/spring-boot/src/main/java/org/baeldung/boot/client/Details.java similarity index 93% rename from spring-boot/src/main/java/org/baeldung/client/Details.java rename to spring-boot/src/main/java/org/baeldung/boot/client/Details.java index 2ae3adc38f..1e3ddf7b21 100644 --- a/spring-boot/src/main/java/org/baeldung/client/Details.java +++ b/spring-boot/src/main/java/org/baeldung/boot/client/Details.java @@ -1,4 +1,4 @@ -package org.baeldung.client; +package org.baeldung.boot.client; public class Details { diff --git a/spring-boot/src/main/java/org/baeldung/client/DetailsServiceClient.java b/spring-boot/src/main/java/org/baeldung/boot/client/DetailsServiceClient.java similarity index 93% rename from spring-boot/src/main/java/org/baeldung/client/DetailsServiceClient.java rename to spring-boot/src/main/java/org/baeldung/boot/client/DetailsServiceClient.java index 51fa7c6181..f2b9d6d030 100644 --- a/spring-boot/src/main/java/org/baeldung/client/DetailsServiceClient.java +++ b/spring-boot/src/main/java/org/baeldung/boot/client/DetailsServiceClient.java @@ -1,4 +1,4 @@ -package org.baeldung.client; +package org.baeldung.boot.client; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.stereotype.Service; diff --git a/spring-boot/src/main/java/org/baeldung/config/H2JpaConfig.java b/spring-boot/src/main/java/org/baeldung/boot/config/H2JpaConfig.java similarity index 89% rename from spring-boot/src/main/java/org/baeldung/config/H2JpaConfig.java rename to spring-boot/src/main/java/org/baeldung/boot/config/H2JpaConfig.java index 62791bf180..4e4b2e06bd 100644 --- a/spring-boot/src/main/java/org/baeldung/config/H2JpaConfig.java +++ b/spring-boot/src/main/java/org/baeldung/boot/config/H2JpaConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.config; +package org.baeldung.boot.config; import java.util.Properties; @@ -18,7 +18,7 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration -@EnableJpaRepositories(basePackages = { "org.baeldung.repository", "org.baeldung.boot.repository", "org.baeldung.boot.boottest" }) +@EnableJpaRepositories(basePackages = { "org.baeldung.boot.repository", "org.baeldung.boot.boottest","org.baeldung.repository" }) @PropertySource("classpath:persistence-generic-entity.properties") @EnableTransactionManagement public class H2JpaConfig { @@ -41,7 +41,7 @@ public class H2JpaConfig { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.domain", "org.baeldung.boot.model", "org.baeldung.boot.boottest" }); + em.setPackagesToScan(new String[] { "org.baeldung.boot.domain", "org.baeldung.boot.model", "org.baeldung.boot.boottest", "org.baeldung.model" }); em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); em.setJpaProperties(additionalProperties()); return em; diff --git a/spring-boot/src/main/java/org/baeldung/boot/config/WebConfig.java b/spring-boot/src/main/java/org/baeldung/boot/config/WebConfig.java new file mode 100644 index 0000000000..caf88c3be7 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/boot/config/WebConfig.java @@ -0,0 +1,28 @@ +package org.baeldung.boot.config; + +import org.baeldung.boot.converter.GenericBigDecimalConverter; +import org.baeldung.boot.converter.StringToEmployeeConverter; +import org.baeldung.boot.converter.StringToEnumConverterFactory; +import org.baeldung.boot.web.resolver.HeaderVersionArgumentResolver; +import org.springframework.context.annotation.Configuration; +import org.springframework.format.FormatterRegistry; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +import java.util.List; + +@Configuration +public class WebConfig extends WebMvcConfigurerAdapter { + + @Override + public void addArgumentResolvers(final List argumentResolvers) { + argumentResolvers.add(new HeaderVersionArgumentResolver()); + } + + @Override + public void addFormatters(FormatterRegistry registry) { + registry.addConverter(new StringToEmployeeConverter()); + registry.addConverterFactory(new StringToEnumConverterFactory()); + registry.addConverter(new GenericBigDecimalConverter()); + } +} diff --git a/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java b/spring-boot/src/main/java/org/baeldung/boot/controller/GenericEntityController.java similarity index 92% rename from spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java rename to spring-boot/src/main/java/org/baeldung/boot/controller/GenericEntityController.java index a9e7dee0b7..8b038e0335 100644 --- a/spring-boot/src/main/java/org/baeldung/controller/GenericEntityController.java +++ b/spring-boot/src/main/java/org/baeldung/boot/controller/GenericEntityController.java @@ -1,8 +1,8 @@ -package org.baeldung.controller; +package org.baeldung.boot.controller; -import org.baeldung.domain.GenericEntity; -import org.baeldung.domain.Modes; -import org.baeldung.web.resolver.Version; +import org.baeldung.boot.domain.GenericEntity; +import org.baeldung.boot.domain.Modes; +import org.baeldung.boot.web.resolver.Version; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; diff --git a/spring-boot/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java b/spring-boot/src/main/java/org/baeldung/boot/controller/servlet/HelloWorldServlet.java similarity index 93% rename from spring-boot/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java rename to spring-boot/src/main/java/org/baeldung/boot/controller/servlet/HelloWorldServlet.java index 9adaf7fd29..34ad11254c 100644 --- a/spring-boot/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java +++ b/spring-boot/src/main/java/org/baeldung/boot/controller/servlet/HelloWorldServlet.java @@ -1,43 +1,43 @@ -package org.baeldung.controller.servlet; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Objects; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class HelloWorldServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - public HelloWorldServlet() { - super(); - } - - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - PrintWriter out = null; - try { - out = response.getWriter(); - out.println("HelloWorldServlet: GET METHOD"); - out.flush(); - } finally { - if (!Objects.isNull(out)) - out.close(); - } - } - - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - PrintWriter out = null; - try { - out = response.getWriter(); - out.println("HelloWorldServlet: POST METHOD"); - out.flush(); - } finally { - if (!Objects.isNull(out)) - out.close(); - } - } - -} +package org.baeldung.boot.controller.servlet; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Objects; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class HelloWorldServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + public HelloWorldServlet() { + super(); + } + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + PrintWriter out = null; + try { + out = response.getWriter(); + out.println("HelloWorldServlet: GET METHOD"); + out.flush(); + } finally { + if (!Objects.isNull(out)) + out.close(); + } + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + PrintWriter out = null; + try { + out = response.getWriter(); + out.println("HelloWorldServlet: POST METHOD"); + out.flush(); + } finally { + if (!Objects.isNull(out)) + out.close(); + } + } + +} diff --git a/spring-boot/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java b/spring-boot/src/main/java/org/baeldung/boot/controller/servlet/SpringHelloWorldServlet.java similarity index 93% rename from spring-boot/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java rename to spring-boot/src/main/java/org/baeldung/boot/controller/servlet/SpringHelloWorldServlet.java index 9a62bdbbf2..91547683c6 100644 --- a/spring-boot/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java +++ b/spring-boot/src/main/java/org/baeldung/boot/controller/servlet/SpringHelloWorldServlet.java @@ -1,43 +1,43 @@ -package org.baeldung.controller.servlet; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Objects; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public class SpringHelloWorldServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - - public SpringHelloWorldServlet() { - super(); - } - - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - PrintWriter out = null; - try { - out = response.getWriter(); - out.println("SpringHelloWorldServlet: GET METHOD"); - out.flush(); - } finally { - if (!Objects.isNull(out)) - out.close(); - } - } - - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - PrintWriter out = null; - try { - out = response.getWriter(); - out.println("SpringHelloWorldServlet: POST METHOD"); - out.flush(); - } finally { - if (!Objects.isNull(out)) - out.close(); - } - } - -} +package org.baeldung.boot.controller.servlet; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Objects; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class SpringHelloWorldServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + public SpringHelloWorldServlet() { + super(); + } + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + PrintWriter out = null; + try { + out = response.getWriter(); + out.println("SpringHelloWorldServlet: GET METHOD"); + out.flush(); + } finally { + if (!Objects.isNull(out)) + out.close(); + } + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + PrintWriter out = null; + try { + out = response.getWriter(); + out.println("SpringHelloWorldServlet: POST METHOD"); + out.flush(); + } finally { + if (!Objects.isNull(out)) + out.close(); + } + } + +} diff --git a/spring-boot/src/main/java/org/baeldung/boot/converter/GenericBigDecimalConverter.java b/spring-boot/src/main/java/org/baeldung/boot/converter/GenericBigDecimalConverter.java new file mode 100644 index 0000000000..decd8ac5db --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/boot/converter/GenericBigDecimalConverter.java @@ -0,0 +1,38 @@ +package org.baeldung.boot.converter; + +import com.google.common.collect.ImmutableSet; +import org.springframework.core.convert.TypeDescriptor; +import org.springframework.core.convert.converter.GenericConverter; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.Set; + +public class GenericBigDecimalConverter implements GenericConverter { + @Override + public Set getConvertibleTypes () { + + ConvertiblePair[] pairs = new ConvertiblePair[] { + new ConvertiblePair(Number.class, BigDecimal.class), + new ConvertiblePair(String.class, BigDecimal.class)}; + + return ImmutableSet.copyOf(pairs); + } + + @Override + public Object convert (Object source, TypeDescriptor sourceType, + TypeDescriptor targetType) { + if (sourceType.getType() == BigDecimal.class) { + return source; + } + + if(sourceType.getType() == String.class) { + String number = (String) source; + return new BigDecimal(number); + } else { + Number number = (Number) source; + BigDecimal converted = new BigDecimal(number.doubleValue()); + return converted.setScale(2, BigDecimal.ROUND_HALF_EVEN); + } + } +} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEmployeeConverter.java b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEmployeeConverter.java new file mode 100644 index 0000000000..de9cf3f55a --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEmployeeConverter.java @@ -0,0 +1,14 @@ +package org.baeldung.boot.converter; + + +import com.baeldung.toggle.Employee; +import org.springframework.core.convert.converter.Converter; + +public class StringToEmployeeConverter implements Converter { + + @Override + public Employee convert(String from) { + String[] data = from.split(","); + return new Employee(Long.parseLong(data[0]), Double.parseDouble(data[1])); + } +} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEnumConverterFactory.java similarity index 95% rename from spring-boot/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java rename to spring-boot/src/main/java/org/baeldung/boot/converter/StringToEnumConverterFactory.java index 17c6fd06de..6fa51bfdcc 100644 --- a/spring-boot/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java +++ b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToEnumConverterFactory.java @@ -1,4 +1,4 @@ -package org.baeldung.converter; +package org.baeldung.boot.converter; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; diff --git a/spring-boot/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToLocalDateTimeConverter.java similarity index 92% rename from spring-boot/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java rename to spring-boot/src/main/java/org/baeldung/boot/converter/StringToLocalDateTimeConverter.java index cbb9e6ddb4..8a08b438f2 100644 --- a/spring-boot/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java +++ b/spring-boot/src/main/java/org/baeldung/boot/converter/StringToLocalDateTimeConverter.java @@ -1,4 +1,4 @@ -package org.baeldung.converter; +package org.baeldung.boot.converter; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; diff --git a/spring-boot/src/main/java/org/baeldung/boot/converter/controller/StringToEmployeeConverterController.java b/spring-boot/src/main/java/org/baeldung/boot/converter/controller/StringToEmployeeConverterController.java new file mode 100644 index 0000000000..ad921c2c43 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/boot/converter/controller/StringToEmployeeConverterController.java @@ -0,0 +1,16 @@ +package org.baeldung.boot.converter.controller; + +import com.baeldung.toggle.Employee; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/string-to-employee") +public class StringToEmployeeConverterController { + + @GetMapping + public ResponseEntity getStringToEmployee(@RequestParam("employee") Employee employee) { + return ResponseEntity.ok(employee); + } +} diff --git a/spring-boot/src/main/java/org/baeldung/domain/GenericEntity.java b/spring-boot/src/main/java/org/baeldung/boot/domain/GenericEntity.java similarity index 95% rename from spring-boot/src/main/java/org/baeldung/domain/GenericEntity.java rename to spring-boot/src/main/java/org/baeldung/boot/domain/GenericEntity.java index 7b1d27cb66..f1c936e432 100644 --- a/spring-boot/src/main/java/org/baeldung/domain/GenericEntity.java +++ b/spring-boot/src/main/java/org/baeldung/boot/domain/GenericEntity.java @@ -1,4 +1,4 @@ -package org.baeldung.domain; +package org.baeldung.boot.domain; import javax.persistence.Entity; import javax.persistence.GeneratedValue; diff --git a/spring-boot/src/main/java/org/baeldung/domain/Modes.java b/spring-boot/src/main/java/org/baeldung/boot/domain/Modes.java similarity index 54% rename from spring-boot/src/main/java/org/baeldung/domain/Modes.java rename to spring-boot/src/main/java/org/baeldung/boot/domain/Modes.java index 473406ef26..dcba064e8c 100644 --- a/spring-boot/src/main/java/org/baeldung/domain/Modes.java +++ b/spring-boot/src/main/java/org/baeldung/boot/domain/Modes.java @@ -1,4 +1,4 @@ -package org.baeldung.domain; +package org.baeldung.boot.domain; public enum Modes { diff --git a/spring-boot/src/main/java/org/baeldung/jsoncomponent/User.java b/spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/User.java similarity index 86% rename from spring-boot/src/main/java/org/baeldung/jsoncomponent/User.java rename to spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/User.java index 8961874526..1f14131300 100644 --- a/spring-boot/src/main/java/org/baeldung/jsoncomponent/User.java +++ b/spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/User.java @@ -1,4 +1,4 @@ -package org.baeldung.jsoncomponent; +package org.baeldung.boot.jsoncomponent; import javafx.scene.paint.Color; diff --git a/spring-boot/src/main/java/org/baeldung/jsoncomponent/UserCombinedSerializer.java b/spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/UserCombinedSerializer.java similarity index 97% rename from spring-boot/src/main/java/org/baeldung/jsoncomponent/UserCombinedSerializer.java rename to spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/UserCombinedSerializer.java index cb1b838ca4..4d3a2cf99e 100644 --- a/spring-boot/src/main/java/org/baeldung/jsoncomponent/UserCombinedSerializer.java +++ b/spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/UserCombinedSerializer.java @@ -1,4 +1,4 @@ -package org.baeldung.jsoncomponent; +package org.baeldung.boot.jsoncomponent; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; diff --git a/spring-boot/src/main/java/org/baeldung/jsoncomponent/UserJsonDeserializer.java b/spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/UserJsonDeserializer.java similarity index 95% rename from spring-boot/src/main/java/org/baeldung/jsoncomponent/UserJsonDeserializer.java rename to spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/UserJsonDeserializer.java index a310dcba5a..ad82ca06c0 100644 --- a/spring-boot/src/main/java/org/baeldung/jsoncomponent/UserJsonDeserializer.java +++ b/spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/UserJsonDeserializer.java @@ -1,4 +1,4 @@ -package org.baeldung.jsoncomponent; +package org.baeldung.boot.jsoncomponent; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/spring-boot/src/main/java/org/baeldung/jsoncomponent/UserJsonSerializer.java b/spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/UserJsonSerializer.java similarity index 96% rename from spring-boot/src/main/java/org/baeldung/jsoncomponent/UserJsonSerializer.java rename to spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/UserJsonSerializer.java index 845bc3aac5..03330d81a4 100644 --- a/spring-boot/src/main/java/org/baeldung/jsoncomponent/UserJsonSerializer.java +++ b/spring-boot/src/main/java/org/baeldung/boot/jsoncomponent/UserJsonSerializer.java @@ -1,4 +1,4 @@ -package org.baeldung.jsoncomponent; +package org.baeldung.boot.jsoncomponent; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/spring-boot/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java b/spring-boot/src/main/java/org/baeldung/boot/monitor/jmx/MonitoringConfig.java similarity index 90% rename from spring-boot/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java rename to spring-boot/src/main/java/org/baeldung/boot/monitor/jmx/MonitoringConfig.java index 40f36ef924..d2e8fc228f 100644 --- a/spring-boot/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java +++ b/spring-boot/src/main/java/org/baeldung/boot/monitor/jmx/MonitoringConfig.java @@ -1,22 +1,22 @@ -package org.baeldung.monitor.jmx; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.codahale.metrics.JmxReporter; -import com.codahale.metrics.MetricRegistry; - -@Configuration -public class MonitoringConfig { - @Autowired - private MetricRegistry registry; - - @Bean - public JmxReporter jmxReporter() { - JmxReporter reporter = JmxReporter.forRegistry(registry) - .build(); - reporter.start(); - return reporter; - } -} +package org.baeldung.boot.monitor.jmx; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.codahale.metrics.JmxReporter; +import com.codahale.metrics.MetricRegistry; + +@Configuration +public class MonitoringConfig { + @Autowired + private MetricRegistry registry; + + @Bean + public JmxReporter jmxReporter() { + JmxReporter reporter = JmxReporter.forRegistry(registry) + .build(); + reporter.start(); + return reporter; + } +} diff --git a/spring-boot/src/main/java/org/baeldung/repository/GenericEntityRepository.java b/spring-boot/src/main/java/org/baeldung/boot/repository/GenericEntityRepository.java similarity index 64% rename from spring-boot/src/main/java/org/baeldung/repository/GenericEntityRepository.java rename to spring-boot/src/main/java/org/baeldung/boot/repository/GenericEntityRepository.java index 7bb1e6dcdc..d897e17afe 100644 --- a/spring-boot/src/main/java/org/baeldung/repository/GenericEntityRepository.java +++ b/spring-boot/src/main/java/org/baeldung/boot/repository/GenericEntityRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.repository; +package org.baeldung.boot.repository; -import org.baeldung.domain.GenericEntity; +import org.baeldung.boot.domain.GenericEntity; import org.springframework.data.jpa.repository.JpaRepository; public interface GenericEntityRepository extends JpaRepository { diff --git a/spring-boot/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java b/spring-boot/src/main/java/org/baeldung/boot/web/resolver/HeaderVersionArgumentResolver.java similarity index 96% rename from spring-boot/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java rename to spring-boot/src/main/java/org/baeldung/boot/web/resolver/HeaderVersionArgumentResolver.java index 89a77f38d1..b3a0dba7e8 100644 --- a/spring-boot/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java +++ b/spring-boot/src/main/java/org/baeldung/boot/web/resolver/HeaderVersionArgumentResolver.java @@ -1,4 +1,4 @@ -package org.baeldung.web.resolver; +package org.baeldung.boot.web.resolver; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; diff --git a/spring-boot/src/main/java/org/baeldung/web/resolver/Version.java b/spring-boot/src/main/java/org/baeldung/boot/web/resolver/Version.java similarity index 86% rename from spring-boot/src/main/java/org/baeldung/web/resolver/Version.java rename to spring-boot/src/main/java/org/baeldung/boot/web/resolver/Version.java index 2a9e6e60b3..f69d40510e 100644 --- a/spring-boot/src/main/java/org/baeldung/web/resolver/Version.java +++ b/spring-boot/src/main/java/org/baeldung/boot/web/resolver/Version.java @@ -1,4 +1,4 @@ -package org.baeldung.web.resolver; +package org.baeldung.boot.web.resolver; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/spring-boot/src/main/java/org/baeldung/config/WebConfig.java b/spring-boot/src/main/java/org/baeldung/config/WebConfig.java deleted file mode 100644 index 4ef407823e..0000000000 --- a/spring-boot/src/main/java/org/baeldung/config/WebConfig.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.baeldung.config; - -import org.baeldung.web.resolver.HeaderVersionArgumentResolver; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; - -import java.util.List; - -@Configuration -public class WebConfig extends WebMvcConfigurerAdapter { - - @Override - public void addArgumentResolvers(final List argumentResolvers) { - argumentResolvers.add(new HeaderVersionArgumentResolver()); - } -} diff --git a/spring-boot/src/main/java/org/baeldung/boot/DemoApplication.java b/spring-boot/src/main/java/org/baeldung/demo/DemoApplication.java similarity index 95% rename from spring-boot/src/main/java/org/baeldung/boot/DemoApplication.java rename to spring-boot/src/main/java/org/baeldung/demo/DemoApplication.java index cb269f77f1..c4b0d48244 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/DemoApplication.java +++ b/spring-boot/src/main/java/org/baeldung/demo/DemoApplication.java @@ -1,4 +1,4 @@ -package org.baeldung.boot; +package org.baeldung.demo; import com.baeldung.graphql.GraphqlConfiguration; import org.springframework.boot.SpringApplication; diff --git a/spring-boot/src/main/java/org/baeldung/boot/boottest/Employee.java b/spring-boot/src/main/java/org/baeldung/demo/boottest/Employee.java similarity index 95% rename from spring-boot/src/main/java/org/baeldung/boot/boottest/Employee.java rename to spring-boot/src/main/java/org/baeldung/demo/boottest/Employee.java index a805e8f5fe..c1dd109f91 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/boottest/Employee.java +++ b/spring-boot/src/main/java/org/baeldung/demo/boottest/Employee.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.boottest; +package org.baeldung.demo.boottest; import javax.persistence.Entity; import javax.persistence.GeneratedValue; diff --git a/spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeRepository.java b/spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeRepository.java similarity index 91% rename from spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeRepository.java rename to spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeRepository.java index 98d1c33212..d991d9a8a9 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeRepository.java +++ b/spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeRepository.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.boottest; +package org.baeldung.demo.boottest; import java.util.List; diff --git a/spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeRestController.java b/spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeRestController.java similarity index 96% rename from spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeRestController.java rename to spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeRestController.java index 1bfde0f0bd..516bff0e8c 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeRestController.java +++ b/spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeRestController.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.boottest; +package org.baeldung.demo.boottest; import java.util.List; diff --git a/spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeService.java b/spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeService.java similarity index 89% rename from spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeService.java rename to spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeService.java index 13b5ca56e0..07765a511c 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeService.java +++ b/spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeService.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.boottest; +package org.baeldung.demo.boottest; import java.util.List; diff --git a/spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeServiceImpl.java b/spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeServiceImpl.java similarity index 96% rename from spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeServiceImpl.java rename to spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeServiceImpl.java index 3fbfa92bc8..bd85234e02 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/boottest/EmployeeServiceImpl.java +++ b/spring-boot/src/main/java/org/baeldung/demo/boottest/EmployeeServiceImpl.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.boottest; +package org.baeldung.demo.boottest; import java.util.List; diff --git a/spring-boot/src/main/java/org/baeldung/boot/components/FooService.java b/spring-boot/src/main/java/org/baeldung/demo/components/FooService.java similarity index 76% rename from spring-boot/src/main/java/org/baeldung/boot/components/FooService.java rename to spring-boot/src/main/java/org/baeldung/demo/components/FooService.java index 4ff8e9fdd4..334730ccb0 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/components/FooService.java +++ b/spring-boot/src/main/java/org/baeldung/demo/components/FooService.java @@ -1,7 +1,7 @@ -package org.baeldung.boot.components; +package org.baeldung.demo.components; -import org.baeldung.boot.model.Foo; -import org.baeldung.boot.repository.FooRepository; +import org.baeldung.demo.model.Foo; +import org.baeldung.demo.repository.FooRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/spring-boot/src/main/java/org/baeldung/boot/exceptions/CommonException.java b/spring-boot/src/main/java/org/baeldung/demo/exceptions/CommonException.java similarity index 85% rename from spring-boot/src/main/java/org/baeldung/boot/exceptions/CommonException.java rename to spring-boot/src/main/java/org/baeldung/demo/exceptions/CommonException.java index e03b859eab..51dd7bbd44 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/exceptions/CommonException.java +++ b/spring-boot/src/main/java/org/baeldung/demo/exceptions/CommonException.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.exceptions; +package org.baeldung.demo.exceptions; public class CommonException extends RuntimeException { diff --git a/spring-boot/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java b/spring-boot/src/main/java/org/baeldung/demo/exceptions/FooNotFoundException.java similarity index 86% rename from spring-boot/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java rename to spring-boot/src/main/java/org/baeldung/demo/exceptions/FooNotFoundException.java index 0b04bd2759..59796c58f0 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java +++ b/spring-boot/src/main/java/org/baeldung/demo/exceptions/FooNotFoundException.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.exceptions; +package org.baeldung.demo.exceptions; public class FooNotFoundException extends RuntimeException { diff --git a/spring-boot/src/main/java/org/baeldung/boot/model/Foo.java b/spring-boot/src/main/java/org/baeldung/demo/model/Foo.java similarity index 95% rename from spring-boot/src/main/java/org/baeldung/boot/model/Foo.java rename to spring-boot/src/main/java/org/baeldung/demo/model/Foo.java index d373e25b85..e5638cfd3d 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/model/Foo.java +++ b/spring-boot/src/main/java/org/baeldung/demo/model/Foo.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.model; +package org.baeldung.demo.model; import java.io.Serializable; diff --git a/spring-boot/src/main/java/org/baeldung/boot/repository/FooRepository.java b/spring-boot/src/main/java/org/baeldung/demo/repository/FooRepository.java similarity index 70% rename from spring-boot/src/main/java/org/baeldung/boot/repository/FooRepository.java rename to spring-boot/src/main/java/org/baeldung/demo/repository/FooRepository.java index 09d6975dba..c04e0c7438 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/repository/FooRepository.java +++ b/spring-boot/src/main/java/org/baeldung/demo/repository/FooRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.boot.repository; +package org.baeldung.demo.repository; -import org.baeldung.boot.model.Foo; +import org.baeldung.demo.model.Foo; import org.springframework.data.jpa.repository.JpaRepository; public interface FooRepository extends JpaRepository { diff --git a/spring-boot/src/main/java/org/baeldung/boot/service/FooController.java b/spring-boot/src/main/java/org/baeldung/demo/service/FooController.java similarity index 85% rename from spring-boot/src/main/java/org/baeldung/boot/service/FooController.java rename to spring-boot/src/main/java/org/baeldung/demo/service/FooController.java index d400c3bf9e..c28dcde1a7 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/service/FooController.java +++ b/spring-boot/src/main/java/org/baeldung/demo/service/FooController.java @@ -1,7 +1,7 @@ -package org.baeldung.boot.service; +package org.baeldung.demo.service; -import org.baeldung.boot.components.FooService; -import org.baeldung.boot.model.Foo; +import org.baeldung.demo.components.FooService; +import org.baeldung.demo.model.Foo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; diff --git a/spring-boot/src/main/java/org/baeldung/endpoints/info/TotalUsersInfoContributor.java b/spring-boot/src/main/java/org/baeldung/endpoints/info/TotalUsersInfoContributor.java index 790584644f..34b50a2c0a 100644 --- a/spring-boot/src/main/java/org/baeldung/endpoints/info/TotalUsersInfoContributor.java +++ b/spring-boot/src/main/java/org/baeldung/endpoints/info/TotalUsersInfoContributor.java @@ -3,7 +3,7 @@ package org.baeldung.endpoints.info; import java.util.HashMap; import java.util.Map; -import org.baeldung.boot.repository.UserRepository; +import org.baeldung.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.info.Info; import org.springframework.boot.actuate.info.InfoContributor; diff --git a/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java b/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java index 2d118b0eae..0ab4ecb128 100644 --- a/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java +++ b/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java @@ -1,9 +1,9 @@ package org.baeldung.main; +import org.baeldung.boot.controller.servlet.HelloWorldServlet; +import org.baeldung.boot.controller.servlet.SpringHelloWorldServlet; import org.baeldung.common.error.SpringHelloServletRegistrationBean; import org.baeldung.common.resources.ExecutorServiceExitCodeGenerator; -import org.baeldung.controller.servlet.HelloWorldServlet; -import org.baeldung.controller.servlet.SpringHelloWorldServlet; import org.baeldung.service.LoginService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; @@ -11,6 +11,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -21,7 +22,7 @@ import java.util.concurrent.Executors; @RestController @EnableAutoConfiguration(exclude = MySQLAutoconfiguration.class) -@ComponentScan({ "org.baeldung.common.error", "org.baeldung.common.error.controller", "org.baeldung.common.properties", "org.baeldung.common.resources", "org.baeldung.endpoints", "org.baeldung.service", "org.baeldung.monitor.jmx", "org.baeldung.service" }) +@ComponentScan({ "org.baeldung.common.error", "org.baeldung.common.error.controller", "org.baeldung.common.properties", "org.baeldung.common.resources","org.baeldung.endpoints", "org.baeldung.service", "org.baeldung.monitor.jmx", "org.baeldung.boot.config"}) public class SpringBootApplication { private static ApplicationContext applicationContext; diff --git a/spring-boot/src/main/java/org/baeldung/boot/model/User.java b/spring-boot/src/main/java/org/baeldung/model/User.java similarity index 95% rename from spring-boot/src/main/java/org/baeldung/boot/model/User.java rename to spring-boot/src/main/java/org/baeldung/model/User.java index f60ac86fe4..61936584c4 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/model/User.java +++ b/spring-boot/src/main/java/org/baeldung/model/User.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.model; +package org.baeldung.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; diff --git a/spring-boot/src/main/java/org/baeldung/boot/repository/UserRepository.java b/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java similarity index 77% rename from spring-boot/src/main/java/org/baeldung/boot/repository/UserRepository.java rename to spring-boot/src/main/java/org/baeldung/repository/UserRepository.java index 3a419a65bd..360dbf883c 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/repository/UserRepository.java +++ b/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.boot.repository; +package org.baeldung.repository; -import org.baeldung.boot.model.User; +import org.baeldung.model.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/spring-boot/src/main/java/org/baeldung/session/exception/Application.java b/spring-boot/src/main/java/org/baeldung/session/exception/Application.java index c0cc669420..70c68368b5 100644 --- a/spring-boot/src/main/java/org/baeldung/session/exception/Application.java +++ b/spring-boot/src/main/java/org/baeldung/session/exception/Application.java @@ -1,6 +1,6 @@ package org.baeldung.session.exception; -import org.baeldung.boot.model.Foo; +import org.baeldung.demo.model.Foo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; diff --git a/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepository.java b/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepository.java index 679d691b26..ce7bbfe57b 100644 --- a/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepository.java +++ b/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepository.java @@ -1,6 +1,6 @@ package org.baeldung.session.exception.repository; -import org.baeldung.boot.model.Foo; +import org.baeldung.demo.model.Foo; public interface FooRepository { diff --git a/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java b/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java index 36d87e6dad..11df542d05 100644 --- a/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java +++ b/spring-boot/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java @@ -1,6 +1,6 @@ package org.baeldung.session.exception.repository; -import org.baeldung.boot.model.Foo; +import org.baeldung.demo.model.Foo; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; diff --git a/spring-boot/src/main/resources/templates/customers.html b/spring-boot/src/main/resources/templates/customers.html new file mode 100644 index 0000000000..5a060d31da --- /dev/null +++ b/spring-boot/src/main/resources/templates/customers.html @@ -0,0 +1,33 @@ + + + + + +
    +

    + Hello, --name--. +

    + + + + + + + + + + + + + + + + + +
    IDNameAddressService Rendered
    Text ...Text ...Text ...Text...
    + +
    + + + diff --git a/spring-boot/src/main/resources/templates/external.html b/spring-boot/src/main/resources/templates/external.html new file mode 100644 index 0000000000..2f9cc76961 --- /dev/null +++ b/spring-boot/src/main/resources/templates/external.html @@ -0,0 +1,31 @@ + + + + + +
    +
    +

    Customer Portal

    +
    +
    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam + erat lectus, vehicula feugiat ultricies at, tempus sed ante. Cras + arcu erat, lobortis vitae quam et, mollis pharetra odio. Nullam sit + amet congue ipsum. Nunc dapibus odio ut ligula venenatis porta non + id dui. Duis nec tempor tellus. Suspendisse id blandit ligula, sit + amet varius mauris. Nulla eu eros pharetra, tristique dui quis, + vehicula libero. Aenean a neque sit amet tellus porttitor rutrum nec + at leo.

    + +

    Existing Customers

    +
    + Enter the intranet: customers +
    +
    + +
    + + + + diff --git a/spring-boot/src/main/resources/templates/layout.html b/spring-boot/src/main/resources/templates/layout.html new file mode 100644 index 0000000000..bab0c2982b --- /dev/null +++ b/spring-boot/src/main/resources/templates/layout.html @@ -0,0 +1,18 @@ + + + +Customer Portal + + + + + \ No newline at end of file diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java index 358ba942d9..823625f811 100644 --- a/spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java @@ -1,6 +1,7 @@ package org.baeldung; -import org.baeldung.domain.Modes; +import org.baeldung.boot.Application; +import org.baeldung.boot.domain.Modes; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootH2IntegrationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootH2IntegrationTest.java index 185a36e571..2cb2f4dc10 100644 --- a/spring-boot/src/test/java/org/baeldung/SpringBootH2IntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/SpringBootH2IntegrationTest.java @@ -1,8 +1,9 @@ package org.baeldung; -import org.baeldung.config.H2JpaConfig; -import org.baeldung.domain.GenericEntity; -import org.baeldung.repository.GenericEntityRepository; +import org.baeldung.boot.Application; +import org.baeldung.boot.config.H2JpaConfig; +import org.baeldung.boot.domain.GenericEntity; +import org.baeldung.boot.repository.GenericEntityRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java index 7c90622cdc..d9c30c67da 100644 --- a/spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java @@ -1,7 +1,8 @@ package org.baeldung; -import org.baeldung.domain.GenericEntity; -import org.baeldung.repository.GenericEntityRepository; +import org.baeldung.boot.Application; +import org.baeldung.boot.domain.GenericEntity; +import org.baeldung.boot.repository.GenericEntityRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java index 0e8a698f41..17e7d2d9e0 100644 --- a/spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java @@ -1,5 +1,6 @@ package org.baeldung; +import org.baeldung.boot.Application; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/spring-boot/src/test/java/org/baeldung/SpringBootProfileIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/SpringBootProfileIntegrationTest.java index 9dd473f321..1d4ee262b0 100644 --- a/spring-boot/src/test/java/org/baeldung/SpringBootProfileIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/SpringBootProfileIntegrationTest.java @@ -1,8 +1,9 @@ package org.baeldung; +import org.baeldung.boot.Application; +import org.baeldung.boot.domain.GenericEntity; +import org.baeldung.boot.repository.GenericEntityRepository; import org.baeldung.config.H2TestProfileJPAConfig; -import org.baeldung.domain.GenericEntity; -import org.baeldung.repository.GenericEntityRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java index 4fcea35b4a..fba816c681 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java @@ -1,5 +1,6 @@ package org.baeldung.boot; +import org.baeldung.demo.DemoApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/client/DetailsServiceClientIntegrationTest.java similarity index 92% rename from spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java rename to spring-boot/src/test/java/org/baeldung/boot/client/DetailsServiceClientIntegrationTest.java index 0f6c13ae1f..6f1cc66979 100644 --- a/spring-boot/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/boot/client/DetailsServiceClientIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.client; +package org.baeldung.boot.client; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; @@ -14,6 +14,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; +import org.baeldung.boot.client.Details; +import org.baeldung.boot.client.DetailsServiceClient; + @RunWith(SpringRunner.class) @RestClientTest(DetailsServiceClient.class) public class DetailsServiceClientIntegrationTest { diff --git a/spring-boot/src/test/java/org/baeldung/jsoncomponent/UserJsonDeserializerIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/jsoncomponent/UserJsonDeserializerIntegrationTest.java similarity index 89% rename from spring-boot/src/test/java/org/baeldung/jsoncomponent/UserJsonDeserializerIntegrationTest.java rename to spring-boot/src/test/java/org/baeldung/boot/jsoncomponent/UserJsonDeserializerIntegrationTest.java index 4f5af3d0e7..f8b47a23fc 100644 --- a/spring-boot/src/test/java/org/baeldung/jsoncomponent/UserJsonDeserializerIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/boot/jsoncomponent/UserJsonDeserializerIntegrationTest.java @@ -1,7 +1,9 @@ -package org.baeldung.jsoncomponent; +package org.baeldung.boot.jsoncomponent; import com.fasterxml.jackson.databind.ObjectMapper; import javafx.scene.paint.Color; + +import org.baeldung.boot.jsoncomponent.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot/src/test/java/org/baeldung/jsoncomponent/UserJsonSerializerIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/jsoncomponent/UserJsonSerializerIntegrationTest.java similarity index 90% rename from spring-boot/src/test/java/org/baeldung/jsoncomponent/UserJsonSerializerIntegrationTest.java rename to spring-boot/src/test/java/org/baeldung/boot/jsoncomponent/UserJsonSerializerIntegrationTest.java index ac47c5e5d9..060374e8fa 100644 --- a/spring-boot/src/test/java/org/baeldung/jsoncomponent/UserJsonSerializerIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/boot/jsoncomponent/UserJsonSerializerIntegrationTest.java @@ -1,4 +1,4 @@ -package org.baeldung.jsoncomponent; +package org.baeldung.boot.jsoncomponent; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -11,6 +11,8 @@ import org.springframework.test.context.junit4.SpringRunner; import static org.junit.Assert.assertEquals; +import org.baeldung.boot.jsoncomponent.User; + @JsonTest @RunWith(SpringRunner.class) public class UserJsonSerializerIntegrationTest { diff --git a/spring-boot/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java index a844b26b2d..5d02d34f53 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java @@ -3,7 +3,8 @@ package org.baeldung.boot.repository; import static org.junit.Assert.assertThat; import org.baeldung.boot.DemoApplicationIntegrationTest; -import org.baeldung.boot.model.Foo; +import org.baeldung.demo.model.Foo; +import org.baeldung.demo.repository.FooRepository; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.is; diff --git a/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java index be992bcc36..4658861162 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java @@ -5,7 +5,7 @@ import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.assertThat; import org.baeldung.boot.ApplicationIntegrationTest; -import org.baeldung.boot.model.Foo; +import org.baeldung.demo.model.Foo; import org.baeldung.session.exception.repository.FooRepository; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java index 55b7fa7216..8de7068949 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java @@ -1,7 +1,7 @@ package org.baeldung.boot.repository; import org.baeldung.boot.ApplicationIntegrationTest; -import org.baeldung.boot.model.Foo; +import org.baeldung.demo.model.Foo; import org.baeldung.session.exception.repository.FooRepository; import org.hibernate.HibernateException; import org.junit.Test; diff --git a/spring-boot/src/test/java/org/baeldung/config/H2TestProfileJPAConfig.java b/spring-boot/src/test/java/org/baeldung/config/H2TestProfileJPAConfig.java index eff383b440..499a755ae7 100644 --- a/spring-boot/src/test/java/org/baeldung/config/H2TestProfileJPAConfig.java +++ b/spring-boot/src/test/java/org/baeldung/config/H2TestProfileJPAConfig.java @@ -41,7 +41,7 @@ public class H2TestProfileJPAConfig { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.domain", "org.baeldung.boot.model", "org.baeldung.boot.boottest" }); + em.setPackagesToScan(new String[] { "org.baeldung.domain", "org.baeldung.boot.domain", "org.baeldung.boot.boottest","org.baeldung.model" }); em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); em.setJpaProperties(additionalProperties()); return em; diff --git a/spring-boot/src/test/java/org/baeldung/converter/CustomConverterTest.java b/spring-boot/src/test/java/org/baeldung/converter/CustomConverterTest.java new file mode 100644 index 0000000000..fb773fc44c --- /dev/null +++ b/spring-boot/src/test/java/org/baeldung/converter/CustomConverterTest.java @@ -0,0 +1,54 @@ +package org.baeldung.converter; + +import com.baeldung.toggle.Employee; + +import org.baeldung.boot.Application; +import org.baeldung.boot.domain.Modes; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.convert.ConversionService; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import java.math.BigDecimal; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = Application.class) +@WebAppConfiguration +public class CustomConverterTest { + + @Autowired + ConversionService conversionService; + + @Test + public void whenConvertStringToIntegerUsingDefaultConverter_thenSuccess() { + assertThat(conversionService.convert("25", Integer.class)).isEqualTo(25); + } + + @Test + public void whenConvertStringToEmployee_thenSuccess() { + Employee employee = conversionService.convert("1,50000.00", Employee.class); + Employee actualEmployee = new Employee(1, 50000.00); + assertThat(conversionService.convert("1,50000.00", Employee.class)) + .isEqualToComparingFieldByField(actualEmployee); + } + + @Test + public void whenConvertStringToEnum_thenSuccess() { + assertThat(conversionService.convert("ALPHA", Modes.class)).isEqualTo(Modes.ALPHA); + } + + @Test + public void whenConvertingToBigDecimalUsingGenericConverter_thenSuccess() { + assertThat(conversionService.convert(Integer.valueOf(11), BigDecimal.class)) + .isEqualTo(BigDecimal.valueOf(11.00).setScale(2, BigDecimal.ROUND_HALF_EVEN)); + assertThat(conversionService.convert(Double.valueOf(25.23), BigDecimal.class)) + .isEqualByComparingTo(BigDecimal.valueOf(Double.valueOf(25.23))); + assertThat(conversionService.convert("2.32", BigDecimal.class)) + .isEqualTo(BigDecimal.valueOf(2.32)); + } +} \ No newline at end of file diff --git a/spring-boot/src/test/java/org/baeldung/converter/controller/StringToEmployeeConverterControllerTest.java b/spring-boot/src/test/java/org/baeldung/converter/controller/StringToEmployeeConverterControllerTest.java new file mode 100644 index 0000000000..06c3f740c2 --- /dev/null +++ b/spring-boot/src/test/java/org/baeldung/converter/controller/StringToEmployeeConverterControllerTest.java @@ -0,0 +1,35 @@ +package org.baeldung.converter.controller; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import static org.hamcrest.CoreMatchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.baeldung.boot.Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class) +@AutoConfigureMockMvc +public class StringToEmployeeConverterControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void getStringToEmployeeTest() throws Exception { + mockMvc.perform(get("/string-to-employee?employee=1,2000")) + .andDo(print()) + .andExpect(jsonPath("$.id", is(1))) + .andExpect(jsonPath("$.salary", is(2000.0))) + .andExpect(status().isOk()); + } +} diff --git a/spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeControllerIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeControllerIntegrationTest.java similarity index 93% rename from spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeControllerIntegrationTest.java rename to spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeControllerIntegrationTest.java index 2146fc09bc..f06c144908 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeControllerIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeControllerIntegrationTest.java @@ -1,5 +1,8 @@ -package org.baeldung.boot.boottest; +package org.baeldung.demo.boottest; +import org.baeldung.demo.boottest.Employee; +import org.baeldung.demo.boottest.EmployeeRestController; +import org.baeldung.demo.boottest.EmployeeService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeRepositoryIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeRepositoryIntegrationTest.java similarity index 94% rename from spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeRepositoryIntegrationTest.java rename to spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeRepositoryIntegrationTest.java index ebde0e243a..221beda900 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeRepositoryIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeRepositoryIntegrationTest.java @@ -1,5 +1,7 @@ -package org.baeldung.boot.boottest; +package org.baeldung.demo.boottest; +import org.baeldung.demo.boottest.Employee; +import org.baeldung.demo.boottest.EmployeeRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; diff --git a/spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeRestControllerIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeRestControllerIntegrationTest.java similarity index 94% rename from spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeRestControllerIntegrationTest.java rename to spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeRestControllerIntegrationTest.java index 9e5613ab10..e6f2203476 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeRestControllerIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeRestControllerIntegrationTest.java @@ -1,6 +1,8 @@ -package org.baeldung.boot.boottest; +package org.baeldung.demo.boottest; -import org.baeldung.boot.DemoApplication; +import org.baeldung.demo.DemoApplication; +import org.baeldung.demo.boottest.Employee; +import org.baeldung.demo.boottest.EmployeeRepository; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeServiceImplIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeServiceImplIntegrationTest.java similarity index 94% rename from spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeServiceImplIntegrationTest.java rename to spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeServiceImplIntegrationTest.java index 9837b02df6..58ef3d4081 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/boottest/EmployeeServiceImplIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeServiceImplIntegrationTest.java @@ -1,5 +1,9 @@ -package org.baeldung.boot.boottest; +package org.baeldung.demo.boottest; +import org.baeldung.demo.boottest.Employee; +import org.baeldung.demo.boottest.EmployeeRepository; +import org.baeldung.demo.boottest.EmployeeService; +import org.baeldung.demo.boottest.EmployeeServiceImpl; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-boot/src/test/java/org/baeldung/boot/boottest/JsonUtil.java b/spring-boot/src/test/java/org/baeldung/demo/boottest/JsonUtil.java similarity index 91% rename from spring-boot/src/test/java/org/baeldung/boot/boottest/JsonUtil.java rename to spring-boot/src/test/java/org/baeldung/demo/boottest/JsonUtil.java index 36d07164b2..7e04f47696 100644 --- a/spring-boot/src/test/java/org/baeldung/boot/boottest/JsonUtil.java +++ b/spring-boot/src/test/java/org/baeldung/demo/boottest/JsonUtil.java @@ -1,4 +1,4 @@ -package org.baeldung.boot.boottest; +package org.baeldung.demo.boottest; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/spring-boot/src/test/resources/data.sql b/spring-boot/src/test/resources/data.sql new file mode 100644 index 0000000000..f36e034ce1 --- /dev/null +++ b/spring-boot/src/test/resources/data.sql @@ -0,0 +1,5 @@ +INSERT INTO country (name) VALUES ('India'); +INSERT INTO country (name) VALUES ('Brazil'); +INSERT INTO country (name) VALUES ('USA'); +INSERT INTO country (name) VALUES ('Italy'); +COMMIT; diff --git a/spring-boot/src/test/resources/schema.sql b/spring-boot/src/test/resources/schema.sql new file mode 100644 index 0000000000..15d7788cd7 --- /dev/null +++ b/spring-boot/src/test/resources/schema.sql @@ -0,0 +1,5 @@ +CREATE TABLE country ( + id INTEGER NOT NULL AUTO_INCREMENT, + name VARCHAR(128) NOT NULL, + PRIMARY KEY (id) +); diff --git a/spring-cloud-cli/README.md b/spring-cloud-cli/README.md new file mode 100644 index 0000000000..5f83ab06fa --- /dev/null +++ b/spring-cloud-cli/README.md @@ -0,0 +1,6 @@ +========= + +## Spring Cloud CLI + +### Relevant Articles: +- [Introduction to Spring Cloud CLI](http://www.baeldung.com/introduction-to-spring-cloud-cli/) \ No newline at end of file diff --git a/spring-cloud-cli/decrypt.sh b/spring-cloud-cli/decrypt.sh new file mode 100644 index 0000000000..450ac156bc --- /dev/null +++ b/spring-cloud-cli/decrypt.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +echo Decrypting my_value as key my_key +spring decrypt --key my_key +echo +echo You should see: \"my_value\" +echo \ No newline at end of file diff --git a/spring-cloud-cli/encrypt.sh b/spring-cloud-cli/encrypt.sh new file mode 100644 index 0000000000..a5ea678952 --- /dev/null +++ b/spring-cloud-cli/encrypt.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +echo Encrypting my_value as key my_key +spring encrypt my_value --key my_key +echo +echo You should see something like: c93cb36ce1d09d7d62dffd156ef742faaa56f97f135ebd05e90355f80290ce6b +echo +echo You can use: \"{cipher}c93cb36ce1d09d7d62dffd156ef742faaa56f97f135ebd05e90355f80290ce6b\" in your configuration files +echo \ No newline at end of file diff --git a/spring-cloud-cli/groovy.sh b/spring-cloud-cli/groovy.sh new file mode 100644 index 0000000000..19f785989b --- /dev/null +++ b/spring-cloud-cli/groovy.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +echo "Run Groovy Rest API Server" +echo "spring run restapi.groovy" +echo "http://localhost:8080/api/get" +spring run restapi.groovy +echo +echo "Run Groovy Eureka Server" +echo "spring run eureka.groovy" +echo "http://localhost:8761" +spring run eureka.groovy +echo \ No newline at end of file diff --git a/spring-cloud-cli/groovy/eureka.groovy b/spring-cloud-cli/groovy/eureka.groovy new file mode 100644 index 0000000000..9f7acdd769 --- /dev/null +++ b/spring-cloud-cli/groovy/eureka.groovy @@ -0,0 +1,2 @@ +@EnableEurekaServer +class Eureka {} \ No newline at end of file diff --git a/spring-cloud-cli/groovy/restapi.groovy b/spring-cloud-cli/groovy/restapi.groovy new file mode 100644 index 0000000000..1526f7f825 --- /dev/null +++ b/spring-cloud-cli/groovy/restapi.groovy @@ -0,0 +1,6 @@ +@RestController +@RequestMapping('/api') +class api { + @GetMapping('/get') + def get() { [message: 'Hello'] } +} \ No newline at end of file diff --git a/spring-cloud-cli/install.sh b/spring-cloud-cli/install.sh new file mode 100644 index 0000000000..e01a8fc22e --- /dev/null +++ b/spring-cloud-cli/install.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +echo See: https://howtoprogram.xyz/2016/08/28/install-spring-boot-command-line-interface-on-linux/ +echo + +echo "Setting up Java JDK 8" +echo See: http://tipsonubuntu.com/2016/07/31/install-oracle-java-8-9-ubuntu-16-04-linux-mint-18/ +sudo add-apt-repository ppa:webupd8team/java +sudo apt-get update +sudo apt-get install oracle-java8-set-default +echo + +echo "Downloading Spring Boot CLI 1.5.7" +wget http://repo.spring.io/release/org/springframework/boot/spring-boot-cli/1.5.7.RELEASE/spring-boot-cli-1.5.7.RELEASE-bin.tar.gz +echo + +echo "Extracting and Installing" +sudo mkdir /opt/spring-boot +sudo tar xzf spring-boot-cli-1.5.7.RELEASE-bin.tar.gz -C /opt/spring-boot +export SPRING_HOME=/opt/spring-boot/spring-1.5.7.RELEASE +export PATH=$SPRING_HOME/bin:$PATH +source /etc/profile +echo + +echo "Verifying Install of Spring CLI" +spring --version +echo + +echo "Maven Install" +sudo apt-get install maven +echo + +echo "Installing JCE" +sudo apt-get install p7zip-full +echo please go to: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html +echo Download the jce_policy-8.zip after you agree to the terms +sleep 25 +sudo 7z x jce_policy-8.zip +sudo mv /usr/lib/jvm/java-8-oracle/jre/lib/security/local_policy.jar /usr/lib/jvm/java-8-oracle/jre/lib/security/local_policy.jar.backup +sudo mv /usr/lib/jvm/java-8-oracle/jre/lib/security/US_export_policy.jar /usr/lib/jvm/java-8-oracle/jre/lib/security/US_export_policy.jar.backup +sudo mv UnlimitedJCEPolicyJDK8/*.jar /usr/lib/jvm/java-8-oracle/jre/lib/security/ +echo + +echo "Installing Spring Cloud CLI" +sudo mkdir /opt/spring-boot/spring-1.5.7.RELEASE/lib/ext +sudo chown -R $USER:$USER /opt/spring-boot/spring-1.5.7.RELEASE/lib/ext +echo see: https://repo.spring.io/snapshot/org/springframework/cloud/spring-cloud-cli/ if manual install required +spring install org.springframework.cloud:spring-cloud-cli:1.3.2.RELEASE +echo + +echo "Verify Installation" +spring cloud --version +echo \ No newline at end of file diff --git a/spring-cloud-cli/spring-cli-cmds.sh b/spring-cloud-cli/spring-cli-cmds.sh new file mode 100644 index 0000000000..6947122a18 --- /dev/null +++ b/spring-cloud-cli/spring-cli-cmds.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +echo "Run Config Server" +echo "spring cloud configserver" +echo "http://localhost:8888" +spring cloud configserver +echo +echo "Run Eureka Server" +echo "spring cloud eureka" +echo "http://localhost:8761" +spring cloud eureka +echo +echo "Run H2 Server" +echo "spring cloud h2" +echo "http://localhost:9095" +spring cloud h2 +echo +echo "Run Kafka Server" +echo "spring cloud kafka" +echo "http://localhost:9091" +spring cloud kafka +echo +echo "Run Zipkin Server" +echo "spring cloud zipkin" +echo "http://localhost:9411" +spring cloud zipkin +echo +echo "Run Dataflow Server" +echo "spring cloud dataflow" +echo "http://localhost:9393" +spring cloud dataflow +echo +echo "Run Hystrixdashboard Server" +echo "spring cloud hystrixdashboard" +echo "http://localhost:7979" +spring cloud hystrixdashboard +echo +echo "List Services" +echo "spring cloud --list" +spring cloud --list +echo \ No newline at end of file diff --git a/spring-cloud-cli/yml/configserver.yml b/spring-cloud-cli/yml/configserver.yml new file mode 100644 index 0000000000..2932bddcbf --- /dev/null +++ b/spring-cloud-cli/yml/configserver.yml @@ -0,0 +1,4 @@ +spring: + profiles: + active: git + cloud.config.server.git.uri: https://github.com/spring-cloud/spring-cloud-cli/tree/master/spring-cloud-launcher/spring-cloud-launcher-configserver \ No newline at end of file diff --git a/spring-cloud-cli/yml/eureka.yml b/spring-cloud-cli/yml/eureka.yml new file mode 100644 index 0000000000..9a21c1ce1c --- /dev/null +++ b/spring-cloud-cli/yml/eureka.yml @@ -0,0 +1,8 @@ +spring: + profiles: + active: git + cloud: + config: + server: + git: + uri: https://github.com/spring-cloud/spring-cloud-cli/tree/master/spring-cloud-launcher/spring-cloud-launcher-eureka \ No newline at end of file diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index e36f5265b2..d11455f90c 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung.spring.cloud @@ -15,6 +15,11 @@ spring-cloud-ribbon-client spring-cloud-rest spring-cloud-zookeeper + spring-cloud-gateway + spring-cloud-stream + spring-cloud-connectors-heroku + spring-cloud-aws + spring-cloud-consul pom @@ -36,6 +41,7 @@ 1.2.3.RELEASE 1.2.3.RELEASE 1.2.3.RELEASE + 1.3.0.RELEASE 1.4.2.RELEASE 3.6.0 1.4.2.RELEASE diff --git a/spring-cloud/spring-cloud-aws/README.md b/spring-cloud/spring-cloud-aws/README.md new file mode 100644 index 0000000000..c5f58159c8 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/README.md @@ -0,0 +1,21 @@ +# Spring Cloud AWS + +#### Running the Integration Tests + +To run the Integration Tests, we need to have an AWS account and have API keys generated for programmatic access. Edit +the `application.properties` file to add the following properties: + +``` +cloud.aws.credentials.accessKey=YourAccessKey +cloud.aws.credentials.secretKey=YourSecretKey +cloud.aws.region.static=us-east-1 +``` + +To test automatic DataSource creation from RDS instance, we also need to create an RDS instance in the AWS account. +Let's say that the RDS instance is called `spring-cloud-test-db` having the master password `se3retpass`, then we need +to write the following in `application.properties`: + +``` +cloud.aws.rds.spring-cloud-test-db +cloud.aws.rds.spring-cloud-test-db.password=se3retpass +``` diff --git a/spring-cloud/spring-cloud-aws/pom.xml b/spring-cloud/spring-cloud-aws/pom.xml new file mode 100644 index 0000000000..632e050d92 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + + com.baeldung.spring.cloud + spring-cloud-aws + 0.0.1-SNAPSHOT + jar + + Spring Cloud AWS + Spring Cloud AWS Examples + + + org.springframework.boot + spring-boot-starter-parent + 1.5.8.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + Dalston.SR4 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-aws + + + org.springframework.cloud + spring-cloud-starter-aws-jdbc + + + org.springframework.cloud + spring-cloud-starter-aws-messaging + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.postgresql + postgresql + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + maven-surefire-plugin + + + **/*IntegrationTest.java + + + + + + + + + diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/SpringCloudAwsApplication.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/SpringCloudAwsApplication.java new file mode 100644 index 0000000000..81bbc579ec --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/SpringCloudAwsApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.spring.cloud.aws; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ImportResource; + +@SpringBootApplication +@ImportResource("classpath:aws-config.xml") +public class SpringCloudAwsApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringCloudAwsApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/config/SpringCloudAwsConfig.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/config/SpringCloudAwsConfig.java new file mode 100644 index 0000000000..85dcd05c86 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/config/SpringCloudAwsConfig.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.cloud.aws.config; + +import com.amazonaws.services.sns.AmazonSNS; +import com.amazonaws.services.sqs.AmazonSQSAsync; +import org.springframework.cloud.aws.messaging.core.NotificationMessagingTemplate; +import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SpringCloudAwsConfig { + + @Bean + public QueueMessagingTemplate queueMessagingTemplate(AmazonSQSAsync amazonSQSAsync) { + return new QueueMessagingTemplate(amazonSQSAsync); + } + + @Bean + public NotificationMessagingTemplate notificationMessagingTemplate(AmazonSNS amazonSNS) { + return new NotificationMessagingTemplate(amazonSNS); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2EnableMetadata.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2EnableMetadata.java new file mode 100644 index 0000000000..03a7db26de --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2EnableMetadata.java @@ -0,0 +1,9 @@ +package com.baeldung.spring.cloud.aws.ec2; + +import org.springframework.cloud.aws.context.config.annotation.EnableContextInstanceData; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableContextInstanceData +public class EC2EnableMetadata { +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2Metadata.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2Metadata.java new file mode 100644 index 0000000000..9466c14560 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2Metadata.java @@ -0,0 +1,62 @@ +package com.baeldung.spring.cloud.aws.ec2; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +@Lazy +@Component +public class EC2Metadata { + + @Value("${ami-id:N/A}") + private String amiId; + + @Value("${hostname:N/A}") + private String hostname; + + @Value("${instance-type:N/A}") + private String instanceType; + + @Value("${services/domain:N/A}") + private String serviceDomain; + + @Value("#{instanceData['Name'] ?: 'N/A'}") + private String name; + + public String getAmiId() { + return amiId; + } + + public String getHostname() { + return hostname; + } + + public String getInstanceType() { + return instanceType; + } + + public String getServiceDomain() { + return serviceDomain; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("EC2Metadata [amiId="); + builder.append(amiId); + builder.append(", hostname="); + builder.append(hostname); + builder.append(", instanceType="); + builder.append(instanceType); + builder.append(", serviceDomain="); + builder.append(serviceDomain); + builder.append(", name="); + builder.append(name); + builder.append("]"); + return builder.toString(); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3.java new file mode 100644 index 0000000000..cfad6e904f --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.cloud.aws.s3; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.WritableResource; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +@Component +public class SpringCloudS3 { + + @Autowired + ResourceLoader resourceLoader; + + @Autowired + ResourcePatternResolver resourcePatternResolver; + + public void downloadS3Object(String s3Url) throws IOException { + Resource resource = resourceLoader.getResource(s3Url); + File downloadedS3Object = new File(resource.getFilename()); + try (InputStream inputStream = resource.getInputStream()) { + Files.copy(inputStream, downloadedS3Object.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } + + public void uploadFileToS3(File file, String s3Url) throws IOException { + WritableResource resource = (WritableResource) resourceLoader.getResource(s3Url); + try (OutputStream outputStream = resource.getOutputStream()) { + Files.copy(file.toPath(), outputStream); + } + } + + public void downloadMultipleS3Objects(String s3UrlPattern) throws IOException { + Resource[] allFileMatchingPatten = this.resourcePatternResolver.getResources(s3UrlPattern); + for (Resource resource : allFileMatchingPatten) { + String fileName = resource.getFilename(); + fileName = fileName.substring(0, fileName.lastIndexOf("/") + 1); + File downloadedS3Object = new File(fileName); + try (InputStream inputStream = resource.getInputStream()) { + Files.copy(inputStream, downloadedS3Object.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointController.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointController.java new file mode 100644 index 0000000000..7c78fcbe37 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointController.java @@ -0,0 +1,36 @@ +package com.baeldung.spring.cloud.aws.sns; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.aws.messaging.config.annotation.NotificationMessage; +import org.springframework.cloud.aws.messaging.config.annotation.NotificationSubject; +import org.springframework.cloud.aws.messaging.endpoint.NotificationStatus; +import org.springframework.cloud.aws.messaging.endpoint.annotation.NotificationMessageMapping; +import org.springframework.cloud.aws.messaging.endpoint.annotation.NotificationSubscriptionMapping; +import org.springframework.cloud.aws.messaging.endpoint.annotation.NotificationUnsubscribeConfirmationMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/topic-subscriber") +public class SNSEndpointController { + + private static final Logger logger = LoggerFactory.getLogger(SNSEndpointController.class); + + @NotificationMessageMapping + public void receiveNotification(@NotificationMessage String message, @NotificationSubject String subject) { + logger.info("Received message: {}, having subject: {}", message, subject); + } + + @NotificationUnsubscribeConfirmationMapping + public void confirmSubscriptionMessage(NotificationStatus notificationStatus) { + logger.info("Unsubscribed from Topic"); + notificationStatus.confirmSubscription(); + } + + @NotificationSubscriptionMapping + public void confirmUnsubscribeMessage(NotificationStatus notificationStatus) { + logger.info("Subscribed to Topic"); + notificationStatus.confirmSubscription(); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSMessageSender.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSMessageSender.java new file mode 100644 index 0000000000..58cb03644b --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSMessageSender.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.aws.sns; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.aws.messaging.core.NotificationMessagingTemplate; +import org.springframework.stereotype.Component; + +@Component +public class SNSMessageSender { + + @Autowired + NotificationMessagingTemplate notificationMessagingTemplate; + + public void send(String topicName, Object message, String subject) { + notificationMessagingTemplate.sendNotification(topicName, message, subject); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQS.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQS.java new file mode 100644 index 0000000000..d2a5fcf9ca --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQS.java @@ -0,0 +1,46 @@ +package com.baeldung.spring.cloud.aws.sqs; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate; +import org.springframework.cloud.aws.messaging.listener.annotation.SqsListener; +import org.springframework.context.annotation.Lazy; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CountDownLatch; + +@Component +@Lazy +public class SpringCloudSQS { + + private static final Logger logger = LoggerFactory.getLogger(SpringCloudSQS.class); + + static final String QUEUE_NAME = "spring-cloud-test-queue"; + + /* + * CountDownLatch is added to wait for messages + * during integration test + */ + CountDownLatch countDownLatch; + + public void setCountDownLatch(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + @Autowired + QueueMessagingTemplate queueMessagingTemplate; + + @SqsListener(QUEUE_NAME) + public void receiveMessage(String message, @Header("SenderId") String senderId) { + logger.info("Received message: {}, having SenderId: {}", message, senderId); + if (countDownLatch != null) { + countDownLatch.countDown(); + } + } + + public void send(String queueName, Object message) { + queueMessagingTemplate.convertAndSend(queueName, message); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/resources/application.properties b/spring-cloud/spring-cloud-aws/src/main/resources/application.properties new file mode 100644 index 0000000000..a769b70ddd --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/resources/application.properties @@ -0,0 +1,14 @@ +cloud.aws.credentials.accessKey=YourAccessKey +cloud.aws.credentials.secretKey=YourSecretKey +cloud.aws.region.static=us-east-1 + +cloud.aws.rds.spring-cloud-test-db +cloud.aws.rds.spring-cloud-test-db.password=se3retpass + +# These 3 properties are optional +cloud.aws.rds.spring-cloud-test-db.username=testuser +cloud.aws.rds.spring-cloud-test-db.readReplicaSupport=true +cloud.aws.rds.spring-cloud-test-db.databaseName=test + +# Disable auto cloudfromation +cloud.aws.stack.auto=false diff --git a/spring-cloud/spring-cloud-aws/src/main/resources/aws-config.xml b/spring-cloud/spring-cloud-aws/src/main/resources/aws-config.xml new file mode 100644 index 0000000000..5ca48f6b1e --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/resources/aws-config.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringCloudAwsTestUtil.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringCloudAwsTestUtil.java new file mode 100644 index 0000000000..fe10eb6f15 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringCloudAwsTestUtil.java @@ -0,0 +1,73 @@ +package com.baeldung.spring.cloud.aws; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.sns.AmazonSNS; +import com.amazonaws.services.sns.AmazonSNSClientBuilder; +import com.amazonaws.services.sqs.AmazonSQS; +import com.amazonaws.services.sqs.AmazonSQSClientBuilder; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.junit.BeforeClass; + +/** + * This class is needed only for testing. This is because we need to + * create AWS resources before Spring's Application context is created + * in a {@link BeforeClass} method. Since Autowired dependencies don't + * work in static context, we will use this class for AWS clients. + */ +public class SpringCloudAwsTestUtil { + + private static String awsAccessKey; + private static String awsSecretKey; + private static String defaultRegion; + + static { + try { + InputStream is = SpringCloudAwsTestUtil.class.getResourceAsStream("/application.properties"); + Properties properties = new Properties(); + properties.load(is); + awsAccessKey = properties.getProperty("cloud.aws.credentials.accessKey"); + awsSecretKey = properties.getProperty("cloud.aws.credentials.secretKey"); + defaultRegion = properties.getProperty("cloud.aws.region.static"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static AWSCredentials awsCredentials() { + return new BasicAWSCredentials(awsAccessKey, awsSecretKey); + } + + public static AWSCredentialsProvider awsCredentialsProvider() { + return new AWSStaticCredentialsProvider(awsCredentials()); + } + + public static AmazonS3 amazonS3() { + return AmazonS3ClientBuilder.standard() + .withCredentials(awsCredentialsProvider()) + .withRegion(defaultRegion) + .build(); + } + + public static AmazonSNS amazonSNS() { + return AmazonSNSClientBuilder.standard() + .withCredentials(awsCredentialsProvider()) + .withRegion(defaultRegion) + .build(); + } + + public static AmazonSQS amazonSQS() { + return AmazonSQSClientBuilder.standard() + .withCredentials(awsCredentialsProvider()) + .withRegion(defaultRegion) + .build(); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataIntegrationTest.java new file mode 100644 index 0000000000..1e75134194 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataIntegrationTest.java @@ -0,0 +1,61 @@ +package com.baeldung.spring.cloud.aws.ec2; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import com.amazonaws.regions.Regions; +import com.amazonaws.services.ec2.AmazonEC2; + +@SpringBootTest +@RunWith(SpringRunner.class) +@TestPropertySource("classpath:application-test.properties") +public class EC2MetadataIntegrationTest { + + private static final Logger logger = LoggerFactory.getLogger(EC2MetadataIntegrationTest.class); + + private boolean serverEc2; + + @Before + public void setUp() { + serverEc2 = Regions.getCurrentRegion() != null; + } + + @Autowired + private EC2Metadata eC2Metadata; + + @Autowired + private AmazonEC2 amazonEC2; + + @Test + public void whenEC2ClinentNotNull_thenSuccess() { + assertThat(amazonEC2).isNotNull(); + } + + @Test + public void whenEC2MetadataNotNull_thenSuccess() { + assertThat(eC2Metadata).isNotNull(); + } + + @Test + public void whenMetdataValuesNotNull_thenSuccess() { + Assume.assumeTrue(serverEc2); + assertThat(eC2Metadata.getAmiId()).isNotEqualTo("N/A"); + assertThat(eC2Metadata.getInstanceType()).isNotEqualTo("N/A"); + } + + @Test + public void whenMetadataLogged_thenSuccess() { + logger.info("Environment is EC2: {}", serverEc2); + logger.info(eC2Metadata.toString()); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSIntegrationTest.java new file mode 100644 index 0000000000..9e163d6dc4 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSIntegrationTest.java @@ -0,0 +1,46 @@ +package com.baeldung.spring.cloud.aws.rds; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@RunWith(SpringRunner.class) +public class SpringCloudRDSIntegrationTest { + + @Autowired + DataSource dataSource; + + @Test + public void whenDataSourceCreated_thenSuccess() { + assertThat(dataSource).isNotNull(); + } + + @Test + public void givenDataSource_whenConnectionCreated_thenSuccess() throws SQLException { + Connection connection = dataSource.getConnection(); + assertThat(connection).isNotNull(); + } + + @Test + public void givenConnection_whenQueryExecuted_thenSuccess() throws SQLException { + Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery("SELECT 1"); + while (resultSet.next()) { + int result = resultSet.getInt(1); + assertThat(result).isEqualTo(1); + } + connection.close(); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3IntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3IntegrationTest.java new file mode 100644 index 0000000000..a866287dec --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3IntegrationTest.java @@ -0,0 +1,101 @@ +package com.baeldung.spring.cloud.aws.s3; + +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.ListObjectsV2Result; +import com.amazonaws.services.s3.model.S3ObjectSummary; +import com.baeldung.spring.cloud.aws.SpringCloudAwsTestUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@RunWith(SpringRunner.class) +@TestPropertySource("classpath:application-test.properties") +public class SpringCloudS3IntegrationTest { + + @Autowired + private SpringCloudS3 springCloudS3; + + private static String bucketName; + private static String testFileToDownload; + private static String testFileToUpload; + + private static String[] filesWithSimilarName; + private static List similarNameFiles; + + @BeforeClass + public static void setupResources() throws IOException { + + bucketName = UUID.randomUUID().toString(); + testFileToDownload = "test-file-download.txt"; + testFileToUpload = "test-file-upload.txt"; + + filesWithSimilarName = new String[] { "foo/hello-apple.txt", "foo/hello-orange.txt", "bar/hello-grapes.txt", }; + + similarNameFiles = new ArrayList<>(); + for (String name : filesWithSimilarName) { + similarNameFiles.add(new File(name.substring(0, name.lastIndexOf("/") + 1))); + } + + Files.write(Paths.get(testFileToUpload), "Hello World Uploaded!".getBytes()); + + AmazonS3 amazonS3 = SpringCloudAwsTestUtil.amazonS3(); + amazonS3.createBucket(bucketName); + + amazonS3.putObject(bucketName, testFileToDownload, "Hello World"); + + for (String s3Key : filesWithSimilarName) { + amazonS3.putObject(bucketName, s3Key, "Hello World"); + } + } + + @Test + public void whenS3ObjectDownloaded_thenSuccess() throws IOException { + String s3Url = "s3://" + bucketName + "/" + testFileToDownload; + springCloudS3.downloadS3Object(s3Url); + assertThat(new File(testFileToDownload)).exists(); + } + + @Test + public void whenS3ObjectUploaded_thenSuccess() throws IOException { + String s3Url = "s3://" + bucketName + "/" + testFileToUpload; + File file = new File(testFileToUpload); + springCloudS3.uploadFileToS3(file, s3Url); + } + + @Test + public void whenMultipleS3ObjectsDownloaded_thenSuccess() throws IOException { + String s3Url = "s3://" + bucketName + "/**/hello-*.txt"; + springCloudS3.downloadMultipleS3Objects(s3Url); + similarNameFiles.forEach(f -> assertThat(f).exists()); + } + + @AfterClass + public static void cleanUpResources() { + AmazonS3 amazonS3 = SpringCloudAwsTestUtil.amazonS3(); + ListObjectsV2Result listObjectsV2Result = amazonS3.listObjectsV2(bucketName); + for (S3ObjectSummary objectSummary : listObjectsV2Result.getObjectSummaries()) { + amazonS3.deleteObject(bucketName, objectSummary.getKey()); + } + amazonS3.deleteBucket(bucketName); + + new File(testFileToDownload).delete(); + new File(testFileToUpload).delete(); + similarNameFiles.forEach(File::delete); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointControllerUnitTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointControllerUnitTest.java new file mode 100644 index 0000000000..14958570e2 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointControllerUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.spring.cloud.aws.sns; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.cloud.aws.messaging.endpoint.NotificationStatus; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; + +public class SNSEndpointControllerUnitTest { + + SNSEndpointController snsEndpointController; + + @Before + public void setUp() { + snsEndpointController = new SNSEndpointController(); + } + + @Test + public void whenReceivedNotificationInvoked_thenSuccess() { + snsEndpointController.receiveNotification("Message", "Subject"); + } + + @Test + public void whenConfirmUnsubscribeReturned_thenSuccess() { + NotificationStatus notificationStatus = mock(NotificationStatus.class); + doNothing().when(notificationStatus).confirmSubscription(); + snsEndpointController.confirmUnsubscribeMessage(notificationStatus); + } + + @Test + public void whenConfirmSubscriptionReturned_thenSuccess() { + NotificationStatus notificationStatus = mock(NotificationStatus.class); + doNothing().when(notificationStatus).confirmSubscription(); + snsEndpointController.confirmSubscriptionMessage(notificationStatus); + } + +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSIntegrationTest.java new file mode 100644 index 0000000000..e1f23d5c76 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSIntegrationTest.java @@ -0,0 +1,61 @@ +package com.baeldung.spring.cloud.aws.sns; + +import java.util.UUID; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import com.amazonaws.services.sns.AmazonSNS; +import com.amazonaws.services.sns.model.CreateTopicResult; +import com.baeldung.spring.cloud.aws.SpringCloudAwsTestUtil; +import com.baeldung.spring.cloud.aws.sqs.Greeting; + +@SpringBootTest +@RunWith(SpringRunner.class) +@TestPropertySource("classpath:application-test.properties") +public class SpringCloudSNSIntegrationTest { + + @Autowired + private SNSMessageSender snsMessageSender; + + private static String topicName; + private static String topicArn; + + @BeforeClass + public static void setupAwsResources() { + + topicName = UUID.randomUUID().toString(); + + AmazonSNS amazonSNS = SpringCloudAwsTestUtil.amazonSNS(); + + CreateTopicResult result = amazonSNS.createTopic(topicName); + topicArn = result.getTopicArn(); + } + + @Test + public void whenMessagePublished_thenSuccess() { + String subject = "Test Message"; + String message = "Hello World"; + snsMessageSender.send(topicName, message, subject); + } + + @Test + public void whenConvertedMessagePublished_thenSuccess() { + String subject = "Test Message"; + Greeting message = new Greeting("Helo", "World"); + snsMessageSender.send(topicName, message, subject); + } + + @AfterClass + public static void cleanupAwsResources() { + AmazonSNS amazonSNS = SpringCloudAwsTestUtil.amazonSNS(); + amazonSNS.deleteTopic(topicArn); + } + +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/Greeting.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/Greeting.java new file mode 100644 index 0000000000..3d14d55f14 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/Greeting.java @@ -0,0 +1,63 @@ +package com.baeldung.spring.cloud.aws.sqs; + +public class Greeting { + private String message; + private String name; + + public Greeting() { + + } + + public Greeting(String mesage, String name) { + this.message = mesage; + this.name = name; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((message == null) ? 0 : message.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Greeting other = (Greeting) obj; + if (message == null) { + if (other.message != null) + return false; + } else if (!message.equals(other.message)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSIntegrationTest.java new file mode 100644 index 0000000000..76d2fd7c0d --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSIntegrationTest.java @@ -0,0 +1,135 @@ +package com.baeldung.spring.cloud.aws.sqs; + +import com.amazonaws.services.sqs.AmazonSQS; +import com.amazonaws.services.sqs.model.CreateQueueResult; +import com.amazonaws.services.sqs.model.PurgeQueueRequest; +import com.amazonaws.services.sqs.model.ReceiveMessageRequest; +import com.amazonaws.services.sqs.model.ReceiveMessageResult; +import com.baeldung.spring.cloud.aws.SpringCloudAwsTestUtil; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Lazy; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.IOException; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@RunWith(SpringRunner.class) +@TestPropertySource("classpath:application-test.properties") +public class SpringCloudSQSIntegrationTest { + + private static final Logger logger = LoggerFactory.getLogger(SpringCloudSQSIntegrationTest.class); + + @Autowired + @Lazy + private SpringCloudSQS springCloudSQS; + + private static String receiveQueueName; + private static String receiveQueueUrl; + + private static String sendQueueName; + private static String sendQueueURl; + + @BeforeClass + public static void setupAwsResources() { + + sendQueueName = UUID.randomUUID().toString(); + receiveQueueName = SpringCloudSQS.QUEUE_NAME; + + AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS(); + + CreateQueueResult receiveQueue = amazonSQS.createQueue(receiveQueueName); + receiveQueueUrl = receiveQueue.getQueueUrl(); + + CreateQueueResult sendQueue = amazonSQS.createQueue(sendQueueName); + sendQueueURl = sendQueue.getQueueUrl(); + } + + @Test + public void whenMessageSentAndVerified_thenSuccess() throws InterruptedException { + + String message = "Hello World"; + springCloudSQS.send(sendQueueName, message); + + AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS(); + + ReceiveMessageRequest request = new ReceiveMessageRequest(sendQueueURl); + request.setMaxNumberOfMessages(1); + + ReceiveMessageResult result = null; + do { + result = amazonSQS.receiveMessage(request); + if (result.getMessages().size() == 0) { + logger.info("Message not received at first time, waiting for 1 second"); + } + } while (result.getMessages().size() == 0); + assertThat(result.getMessages().get(0).getBody()).isEqualTo(message); + + // Delete message so that it doen't interfere with other test + amazonSQS.deleteMessage(sendQueueURl, result.getMessages().get(0).getReceiptHandle()); + + } + + @Test + public void whenConvertedMessageSentAndVerified_thenSuccess() throws InterruptedException, IOException { + + Greeting message = new Greeting("Hello", "World"); + springCloudSQS.send(sendQueueName, message); + + AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS(); + + ReceiveMessageRequest request = new ReceiveMessageRequest(sendQueueURl); + request.setMaxNumberOfMessages(1); + + ReceiveMessageResult result = null; + do { + result = amazonSQS.receiveMessage(request); + if (result.getMessages().size() == 0) { + logger.info("Message not received at first time, waiting for 1 second"); + } + } while (result.getMessages().size() == 0); + assertThat(new ObjectMapper().readValue(result.getMessages().get(0).getBody(), Greeting.class)).isEqualTo(message); + + // Delete message so that it doen't interfere with other test + amazonSQS.deleteMessage(sendQueueURl, result.getMessages().get(0).getReceiptHandle()); + } + + @Test + public void givenMessageSent_whenMessageReceived_thenSuccess() throws InterruptedException { + CountDownLatch countDownLatch = new CountDownLatch(5); + springCloudSQS.setCountDownLatch(countDownLatch); + + AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS(); + for (int i = 0; i < 5; i++) { + amazonSQS.sendMessage(receiveQueueUrl, "Hello World " + i); + logger.info("Sent message {}, waiting for 1 second", i + 1); + Thread.sleep(1000L); + } + countDownLatch.await(); + } + + @AfterClass + public static void cleanupAwsResources() { + AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS(); + PurgeQueueRequest receiveQueuePurge = new PurgeQueueRequest(receiveQueueUrl); + amazonSQS.purgeQueue(receiveQueuePurge); + amazonSQS.deleteQueue(receiveQueueUrl); + + PurgeQueueRequest sendQueuePurge = new PurgeQueueRequest(sendQueueURl); + amazonSQS.purgeQueue(sendQueuePurge); + amazonSQS.deleteQueue(sendQueueURl); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/test/resources/application-test.properties b/spring-cloud/spring-cloud-aws/src/test/resources/application-test.properties new file mode 100644 index 0000000000..0d3d90b03a --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +# Don't try to create DataSouce when running tests which don't need a DataSource +spring.autoconfigure.exclude=\ + org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration,\ + org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration diff --git a/spring-cloud/spring-cloud-connectors-heroku/pom.xml b/spring-cloud/spring-cloud-connectors-heroku/pom.xml new file mode 100644 index 0000000000..ba3f0ef28f --- /dev/null +++ b/spring-cloud/spring-cloud-connectors-heroku/pom.xml @@ -0,0 +1,100 @@ + + + 4.0.0 + + + spring-boot-starter-parent + org.springframework.boot + 1.4.4.RELEASE + + + + com.baeldung.spring.cloud + spring-cloud-connectors-heroku + 1.0.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-cloud-connectors + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-actuator + + + + org.postgresql + postgresql + 9.4-1201-jdbc4 + + + + com.h2database + h2 + runtime + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud-dependencies.version} + pom + import + + + + + + Brixton.SR7 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19.1 + + 3 + true + + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + true + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.0 + + 1.8 + 1.8 + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/ConnectorsHerokuApplication.java b/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/ConnectorsHerokuApplication.java new file mode 100644 index 0000000000..63246e89cc --- /dev/null +++ b/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/ConnectorsHerokuApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.cloud.connectors.heroku; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConnectorsHerokuApplication { + + public static void main(String[] args) { + SpringApplication.run(ConnectorsHerokuApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/Product.java b/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/Product.java new file mode 100644 index 0000000000..40e8809fc5 --- /dev/null +++ b/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/Product.java @@ -0,0 +1,30 @@ +package com.baeldung.spring.cloud.connectors.heroku.product; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Product { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long productId; + private String sku; + + public Long getProductId() { + return productId; + } + + public void setProductId(Long productId) { + this.productId = productId; + } + + public String getSku() { + return sku; + } + + public void setSku(String sku) { + this.sku = sku; + } +} diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/ProductController.java b/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/ProductController.java new file mode 100644 index 0000000000..51cf4412bf --- /dev/null +++ b/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/ProductController.java @@ -0,0 +1,26 @@ +package com.baeldung.spring.cloud.connectors.heroku.product; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/products") +public class ProductController { + + private final ProductService productService; + + @Autowired + public ProductController(ProductService productService) { + this.productService = productService; + } + + @GetMapping("/{productId}") + public Product findProduct(@PathVariable Long productId) { + return productService.findProductById(productId); + } + + @PostMapping + public Product createProduct(@RequestBody Product product) { + return productService.createProduct(product); + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/ProductRepository.java b/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/ProductRepository.java new file mode 100644 index 0000000000..508e1d048b --- /dev/null +++ b/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/ProductRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.spring.cloud.connectors.heroku.product; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ProductRepository extends JpaRepository{ +} diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/ProductService.java b/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/ProductService.java new file mode 100644 index 0000000000..f25b4ecf7b --- /dev/null +++ b/spring-cloud/spring-cloud-connectors-heroku/src/main/java/com/baeldung/spring/cloud/connectors/heroku/product/ProductService.java @@ -0,0 +1,28 @@ +package com.baeldung.spring.cloud.connectors.heroku.product; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +public class ProductService { + private final ProductRepository productRepository; + + @Autowired + public ProductService(ProductRepository productRepository) { + this.productRepository = productRepository; + } + + public Product findProductById(Long productId) { + return productRepository.findOne(productId); + } + + @Transactional(propagation = Propagation.REQUIRED) + public Product createProduct(Product product) { + Product newProduct = new Product(); + newProduct.setSku(product.getSku()); + return productRepository.save(newProduct); + } +} diff --git a/spring-cloud/spring-cloud-connectors-heroku/src/main/resources/application.properties b/spring-cloud/spring-cloud-connectors-heroku/src/main/resources/application.properties new file mode 100644 index 0000000000..d2f1c89dc5 --- /dev/null +++ b/spring-cloud/spring-cloud-connectors-heroku/src/main/resources/application.properties @@ -0,0 +1,8 @@ +spring.datasource.driverClassName=org.postgresql.Driver +spring.datasource.maxActive=10 +spring.datasource.maxIdle=5 +spring.datasource.minIdle=2 +spring.datasource.initialSize=5 +spring.datasource.removeAbandoned=true + +spring.jpa.hibernate.ddl-auto=update \ No newline at end of file diff --git a/spring-cloud/spring-cloud-consul/pom.xml b/spring-cloud/spring-cloud-consul/pom.xml new file mode 100644 index 0000000000..0a0650ec8b --- /dev/null +++ b/spring-cloud/spring-cloud-consul/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + org.baeldung + spring-cloud-consul + jar + + spring-cloud-consul + + + com.baeldung.spring.cloud + spring-cloud + 1.0.0-SNAPSHOT + + + + UTF-8 + 3.6.0 + + + + + org.springframework.cloud + spring-cloud-starter-consul-all + 1.3.0.RELEASE + + + + org.springframework.cloud + spring-cloud-starter-consul-config + 1.3.0.RELEASE + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + + + + diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientApplication.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientApplication.java new file mode 100644 index 0000000000..d013969ad3 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientApplication.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.consul.discovery; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +@SpringBootApplication +@EnableDiscoveryClient +public class DiscoveryClientApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(DiscoveryClientApplication.class).web(true) + .run(args); + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientController.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientController.java new file mode 100644 index 0000000000..1436096d10 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientController.java @@ -0,0 +1,50 @@ +package com.baeldung.spring.cloud.consul.discovery; + +import java.net.URI; +import java.util.Optional; + +import javax.naming.ServiceUnavailableException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +@RestController +public class DiscoveryClientController { + + @Autowired + private DiscoveryClient discoveryClient; + + private final RestTemplate restTemplate = new RestTemplate(); + + @GetMapping("/discoveryClient") + public String discoveryPing() throws RestClientException, ServiceUnavailableException { + URI service = serviceUrl().map(s -> s.resolve("/ping")) + .orElseThrow(ServiceUnavailableException::new); + return restTemplate.getForEntity(service, String.class) + .getBody(); + } + + @GetMapping("/ping") + public String ping() { + return "pong"; + } + + @GetMapping("/my-health-check") + public ResponseEntity myCustomCheck() { + return new ResponseEntity<>(HttpStatus.OK); + } + + public Optional serviceUrl() { + return discoveryClient.getInstances("myApp") + .stream() + .findFirst() + .map(si -> si.getUri()); + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryApplication.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryApplication.java new file mode 100644 index 0000000000..020d7d017c --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.spring.cloud.consul.health; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +public class ServiceDiscoveryApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(ServiceDiscoveryApplication.class).web(true) + .run(args); + } + +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryController.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryController.java new file mode 100644 index 0000000000..20deba993f --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryController.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.cloud.consul.health; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ServiceDiscoveryController { + + @GetMapping("/ping") + public String ping() { + return "pong"; + } + + @GetMapping("/my-health-check") + public ResponseEntity myCustomCheck() { + String message = "Testing my healh check function"; + return new ResponseEntity<>(message, HttpStatus.FORBIDDEN); + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesApplication.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesApplication.java new file mode 100644 index 0000000000..c1d2b0acc5 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesApplication.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.consul.properties; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.web.bind.annotation.RestController; + +@SpringBootApplication +@RestController +public class DistributedPropertiesApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(DistributedPropertiesApplication.class).web(true) + .run(args); + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesController.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesController.java new file mode 100644 index 0000000000..da2d37eb76 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesController.java @@ -0,0 +1,27 @@ +package com.baeldung.spring.cloud.consul.properties; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class DistributedPropertiesController { + + @Value("${my.prop}") + String value; + + @Autowired + private MyProperties properties; + + @GetMapping("/getConfigFromValue") + public String getConfigFromValue() { + return value; + } + + @GetMapping("/getConfigFromProperty") + public String getConfigFromProperty() { + return properties.getProp(); + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/MyProperties.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/MyProperties.java new file mode 100644 index 0000000000..d92b18ed51 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/MyProperties.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.cloud.consul.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +@RefreshScope +@Configuration +@ConfigurationProperties("my") +public class MyProperties { + + private String prop; + + public String getProp() { + return prop; + } + + public void setProp(String prop) { + this.prop = prop; + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/resources/application.yml b/spring-cloud/spring-cloud-consul/src/main/resources/application.yml new file mode 100644 index 0000000000..ccdc3fdeee --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/resources/application.yml @@ -0,0 +1,14 @@ +spring: + application: + name: myApp + cloud: + consul: + host: localhost + port: 8500 + discovery: + healthCheckPath: /my-health-check + healthCheckInterval: 20s + enabled: true + instanceId: ${spring.application.name}:${random.value} +server: + port: 0 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-consul/src/main/resources/bootstrap.yml b/spring-cloud/spring-cloud-consul/src/main/resources/bootstrap.yml new file mode 100644 index 0000000000..6318170135 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/resources/bootstrap.yml @@ -0,0 +1,9 @@ +spring: + application: + name: myApp + cloud: + consul: + host: localhost + port: 8500 + config: + enabled: true \ No newline at end of file diff --git a/spring-cloud/spring-cloud-gateway/README.MD b/spring-cloud/spring-cloud-gateway/README.MD new file mode 100644 index 0000000000..48fbf41b8e --- /dev/null +++ b/spring-cloud/spring-cloud-gateway/README.MD @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Explore the new Spring Cloud Gateway](http://www.baeldung.com/spring-cloud-gateway) diff --git a/spring-cloud/spring-cloud-gateway/gateway-service/pom.xml b/spring-cloud/spring-cloud-gateway/gateway-service/pom.xml new file mode 100644 index 0000000000..14cde4901a --- /dev/null +++ b/spring-cloud/spring-cloud-gateway/gateway-service/pom.xml @@ -0,0 +1,79 @@ + + 4.0.0 + + gateway-service + 1.0.0-SNAPSHOT + jar + + Spring Cloud Gateway Service + + + com.baeldung.spring.cloud + spring-cloud-gateway + 1.0.0-SNAPSHOT + .. + + + + 2.0.0.M2 + + + + + org.springframework.boot + spring-boot-actuator + ${version} + + + org.springframework.boot + spring-boot-starter-webflux + ${version} + + + org.springframework.cloud + spring-cloud-gateway-core + ${version} + + + org.springframework.cloud + spring-cloud-starter-eureka + ${version} + + + org.hibernate + hibernate-validator-cdi + 6.0.2.Final + + + javax.validation + validation-api + 2.0.0.Final + + + io.projectreactor.ipc + reactor-netty + 0.7.0.M1 + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-gateway/gateway-service/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java b/spring-cloud/spring-cloud-gateway/gateway-service/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java new file mode 100644 index 0000000000..4d5f61315f --- /dev/null +++ b/spring-cloud/spring-cloud-gateway/gateway-service/src/main/java/com/baeldung/spring/cloud/GatewayApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.cloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class GatewayApplication { + + public static void main(String[] args) { + SpringApplication.run(GatewayApplication.class, args); + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-gateway/gateway-service/src/main/resources/application.yml b/spring-cloud/spring-cloud-gateway/gateway-service/src/main/resources/application.yml new file mode 100644 index 0000000000..8b981f8071 --- /dev/null +++ b/spring-cloud/spring-cloud-gateway/gateway-service/src/main/resources/application.yml @@ -0,0 +1,13 @@ +server: + port: 80 +spring: + cloud: + gateway: + routes: + - id: baeldung_route + uri: http://www.baeldung.com + predicates: + - Path=/baeldung +management: + security: + enabled: false \ No newline at end of file diff --git a/spring-cloud/spring-cloud-gateway/pom.xml b/spring-cloud/spring-cloud-gateway/pom.xml new file mode 100644 index 0000000000..095ca4ea31 --- /dev/null +++ b/spring-cloud/spring-cloud-gateway/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + com.baeldung.spring.cloud + spring-cloud-gateway + 1.0.0-SNAPSHOT + + gateway-service + + pom + + Spring Cloud Gateway + + + com.baeldung.spring.cloud + spring-cloud + 1.0.0-SNAPSHOT + .. + + + + UTF-8 + 3.6.0 + 1.4.2.RELEASE + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + + + + diff --git a/spring-cloud/spring-cloud-stream/README.md b/spring-cloud/spring-cloud-stream/README.md new file mode 100644 index 0000000000..5ecb852df5 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Introduction to Spring Cloud Stream](http://www.baeldung.com/spring-cloud-stream) diff --git a/spring-cloud/spring-cloud-stream/pom.xml b/spring-cloud/spring-cloud-stream/pom.xml new file mode 100644 index 0000000000..5ec24268d9 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + + org.baeldung + spring-cloud-stream + pom + + spring-cloud-stream + + + com.baeldung.spring.cloud + spring-cloud + 1.0.0-SNAPSHOT + + + + spring-cloud-stream-rabbit + + + + UTF-8 + 3.6.0 + + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + ${spring-cloud-stream.version} + + + + org.springframework.cloud + spring-cloud-stream + ${spring-cloud-stream.version} + + + + org.springframework.cloud + spring-cloud-stream-test-support + ${spring-cloud-stream.version} + test + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + + + + diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml new file mode 100644 index 0000000000..a954a7035e --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + spring-cloud-stream-rabbit + jar + + spring-cloud-stream-rabbit + Simple Spring Cloud Stream + + + org.baeldung + spring-cloud-stream + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + org.springframework.cloud + spring-cloud-stream-test-support + test + + + + diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplication.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplication.java new file mode 100644 index 0000000000..375494dfac --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplication.java @@ -0,0 +1,38 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; + +import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor; + +@SpringBootApplication +@EnableBinding(MyProcessor.class) +public class MultipleOutputsServiceApplication { + public static void main(String[] args) { + SpringApplication.run(MultipleOutputsServiceApplication.class, args); + } + + @Autowired + private MyProcessor processor; + + @StreamListener(MyProcessor.INPUT) + public void routeValues(Integer val) { + if (val < 10) { + processor.anOutput() + .send(message(val)); + } else { + processor.anotherOutput() + .send(message(val)); + } + } + + private static final Message message(T val) { + return MessageBuilder.withPayload(val) + .build(); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceApplication.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceApplication.java new file mode 100644 index 0000000000..4729e418b6 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceApplication.java @@ -0,0 +1,39 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; + +import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor; + +@SpringBootApplication +@EnableBinding(MyProcessor.class) +public class MultipleOutputsWithConditionsServiceApplication { + public static void main(String[] args) { + SpringApplication.run(MultipleOutputsWithConditionsServiceApplication.class, args); + } + + @Autowired + private MyProcessor processor; + + @StreamListener(target = MyProcessor.INPUT, condition = "payload < 10") + public void routeValuesToAnOutput(Integer val) { + processor.anOutput() + .send(message(val)); + } + + @StreamListener(target = MyProcessor.INPUT, condition = "payload >= 10") + public void routeValuesToAnotherOutput(Integer val) { + processor.anotherOutput() + .send(message(val)); + } + + private static final Message message(T val) { + return MessageBuilder.withPayload(val) + .build(); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerServiceApplication.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerServiceApplication.java new file mode 100644 index 0000000000..aac551e544 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerServiceApplication.java @@ -0,0 +1,32 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.cloud.stream.messaging.Processor; +import org.springframework.context.annotation.Bean; +import org.springframework.messaging.converter.MessageConverter; +import org.springframework.messaging.handler.annotation.SendTo; + +import com.baeldung.spring.cloud.stream.rabbit.messages.TextPlainMessageConverter; +import com.baeldung.spring.cloud.stream.rabbit.model.LogMessage; + +@SpringBootApplication +@EnableBinding(Processor.class) +public class MyLoggerServiceApplication { + public static void main(String[] args) { + SpringApplication.run(MyLoggerServiceApplication.class, args); + } + + @Bean + public MessageConverter providesTextPlainMessageConverter() { + return new TextPlainMessageConverter(); + } + + @StreamListener(Processor.INPUT) + @SendTo(Processor.OUTPUT) + public LogMessage enrichLogMessage(LogMessage log) { + return new LogMessage(String.format("[1]: %s", log.getMessage())); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/messages/TextPlainMessageConverter.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/messages/TextPlainMessageConverter.java new file mode 100644 index 0000000000..d690ee38a9 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/messages/TextPlainMessageConverter.java @@ -0,0 +1,26 @@ +package com.baeldung.spring.cloud.stream.rabbit.messages; + +import org.springframework.messaging.Message; +import org.springframework.messaging.converter.AbstractMessageConverter; +import org.springframework.util.MimeType; + +import com.baeldung.spring.cloud.stream.rabbit.model.LogMessage; + +public class TextPlainMessageConverter extends AbstractMessageConverter { + + public TextPlainMessageConverter() { + super(new MimeType("text", "plain")); + } + + @Override + protected boolean supports(Class clazz) { + return (LogMessage.class == clazz); + } + + @Override + protected Object convertFromInternal(Message message, Class targetClass, Object conversionHint) { + Object payload = message.getPayload(); + String text = payload instanceof String ? (String) payload : new String((byte[]) payload); + return new LogMessage(text); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/model/LogMessage.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/model/LogMessage.java new file mode 100644 index 0000000000..44a6ca4d4e --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/model/LogMessage.java @@ -0,0 +1,32 @@ +package com.baeldung.spring.cloud.stream.rabbit.model; + +import java.io.Serializable; + +public class LogMessage implements Serializable { + + private static final long serialVersionUID = -5857383701708275796L; + + private String message; + + public LogMessage() { + + } + + public LogMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return message; + } + +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/processor/MyProcessor.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/processor/MyProcessor.java new file mode 100644 index 0000000000..563ce06b6f --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/processor/MyProcessor.java @@ -0,0 +1,19 @@ +package com.baeldung.spring.cloud.stream.rabbit.processor; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.SubscribableChannel; + +public interface MyProcessor { + String INPUT = "myInput"; + + @Input + SubscribableChannel myInput(); + + @Output("myOutput") + MessageChannel anOutput(); + + @Output + MessageChannel anotherOutput(); +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/resources/application.yml b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/resources/application.yml new file mode 100644 index 0000000000..3d9d97a736 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + cloud: + stream: + bindings: + input: + destination: queue.log.messages + binder: local_rabbit + group: logMessageConsumers + output: + destination: queue.pretty.log.messages + binder: local_rabbit + binders: + local_rabbit: + type: rabbit + environment: + spring: + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + virtual-host: / +server: + port: 0 +management: + health: + binders: + enabled: true \ No newline at end of file diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplicationIntegrationTest.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplicationIntegrationTest.java new file mode 100644 index 0000000000..898d06897f --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplicationIntegrationTest.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.stream.test.binder.MessageCollector; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MultipleOutputsServiceApplication.class) +@DirtiesContext +public class MultipleOutputsServiceApplicationIntegrationTest { + + @Autowired + private MyProcessor pipe; + + @Autowired + private MessageCollector messageCollector; + + @Test + public void whenSendMessage_thenResponseIsInAOutput() { + whenSendMessage(1); + thenPayloadInChannelIs(pipe.anOutput(), 1); + } + + @Test + public void whenSendMessage_thenResponseIsInAnotherOutput() { + whenSendMessage(11); + thenPayloadInChannelIs(pipe.anotherOutput(), 11); + } + + private void whenSendMessage(Integer val) { + pipe.myInput() + .send(MessageBuilder.withPayload(val) + .build()); + } + + private void thenPayloadInChannelIs(MessageChannel channel, Integer expectedValue) { + Object payload = messageCollector.forChannel(channel) + .poll() + .getPayload(); + assertEquals(expectedValue, payload); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceIntegrationTest.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceIntegrationTest.java new file mode 100644 index 0000000000..c3bf5a1205 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceIntegrationTest.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.stream.test.binder.MessageCollector; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MultipleOutputsWithConditionsServiceApplication.class) +@DirtiesContext +public class MultipleOutputsWithConditionsServiceIntegrationTest { + + @Autowired + private MyProcessor pipe; + + @Autowired + private MessageCollector messageCollector; + + @Test + public void whenSendMessage_thenResponseIsInAOutput() { + whenSendMessage(1); + thenPayloadInChannelIs(pipe.anOutput(), 1); + } + + @Test + public void whenSendMessage_thenResponseIsInAnotherOutput() { + whenSendMessage(11); + thenPayloadInChannelIs(pipe.anotherOutput(), 11); + } + + private void whenSendMessage(Integer val) { + pipe.myInput() + .send(MessageBuilder.withPayload(val) + .build()); + } + + private void thenPayloadInChannelIs(MessageChannel channel, Integer expectedValue) { + Object payload = messageCollector.forChannel(channel) + .poll() + .getPayload(); + assertEquals(expectedValue, payload); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerApplicationIntegrationTest.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerApplicationIntegrationTest.java new file mode 100644 index 0000000000..21d84e79e0 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerApplicationIntegrationTest.java @@ -0,0 +1,40 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.stream.messaging.Processor; +import org.springframework.cloud.stream.test.binder.MessageCollector; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.cloud.stream.rabbit.model.LogMessage; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MyLoggerServiceApplication.class) +@DirtiesContext +public class MyLoggerApplicationIntegrationTest { + + @Autowired + private Processor pipe; + + @Autowired + private MessageCollector messageCollector; + + @Test + public void whenSendMessage_thenResponseShouldUpdateText() { + pipe.input() + .send(MessageBuilder.withPayload(new LogMessage("This is my message")) + .build()); + + Object payload = messageCollector.forChannel(pipe.output()) + .poll() + .getPayload(); + + assertEquals("[1]: This is my message", payload.toString()); + } +} diff --git a/spring-core/README.md b/spring-core/README.md index 237f8cd4e9..81a7aaa952 100644 --- a/spring-core/README.md +++ b/spring-core/README.md @@ -8,4 +8,3 @@ - [Spring YAML Configuration](http://www.baeldung.com/spring-yaml) - [Introduction to Spring’s StreamUtils](http://www.baeldung.com/spring-stream-utils) - [Using Spring @Value with Defaults](http://www.baeldung.com/spring-value-defaults) - diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/ArticleFormatter.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/ArticleFormatter.java new file mode 100644 index 0000000000..069e9df084 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/ArticleFormatter.java @@ -0,0 +1,16 @@ +package com.baeldung.dependencyinjectiontypes; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class ArticleFormatter { + + @SuppressWarnings("resource") + public static void main(String[] args) { + ApplicationContext context = new ClassPathXmlApplicationContext("dependencyinjectiontypes-context.xml"); + ArticleWithSetterInjection article = (ArticleWithSetterInjection) context.getBean("articleWithSetterInjectionBean"); + String formattedArticle = article.format("This is a text !"); + + System.out.print(formattedArticle); + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/ArticleWithConstructorInjection.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/ArticleWithConstructorInjection.java new file mode 100644 index 0000000000..776e9f4040 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/ArticleWithConstructorInjection.java @@ -0,0 +1,17 @@ +package com.baeldung.dependencyinjectiontypes; + +import org.springframework.beans.factory.annotation.Autowired; + +public class ArticleWithConstructorInjection { + + private TextFormatter formatter; + + @Autowired + public ArticleWithConstructorInjection(TextFormatter formatter) { + this.formatter = formatter; + } + + public String format(String text) { + return formatter.format(text); + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/ArticleWithSetterInjection.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/ArticleWithSetterInjection.java new file mode 100644 index 0000000000..931c6ea276 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/ArticleWithSetterInjection.java @@ -0,0 +1,21 @@ +package com.baeldung.dependencyinjectiontypes; + +import org.springframework.beans.factory.annotation.Autowired; + +public class ArticleWithSetterInjection { + + private TextFormatter formatter; + + public ArticleWithSetterInjection(TextFormatter formatter) { + this.formatter = formatter; + } + + @Autowired + public void setTextFormatter(TextFormatter formatter) { + this.formatter = formatter; + } + + public String format(String text) { + return formatter.format(text); + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/TextFormatter.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/TextFormatter.java new file mode 100644 index 0000000000..204436c9bd --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/TextFormatter.java @@ -0,0 +1,8 @@ +package com.baeldung.dependencyinjectiontypes; + +public class TextFormatter { + + public String format(String text) { + return text.toUpperCase(); + } +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/IService.java b/spring-core/src/main/java/com/baeldung/di/spring/IService.java new file mode 100644 index 0000000000..478eea0657 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/IService.java @@ -0,0 +1,5 @@ +package com.baeldung.di.spring; + +public interface IService { + public String serve(); +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/IndexApp.java b/spring-core/src/main/java/com/baeldung/di/spring/IndexApp.java new file mode 100644 index 0000000000..a45970d6b2 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/IndexApp.java @@ -0,0 +1,19 @@ +package com.baeldung.di.spring; + +public class IndexApp { + + private IService service; + + public String getServiceValue() { + return service.serve(); + } + + public IService getService() { + return service; + } + + public void setService(IService service) { + this.service = service; + } + +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/IndexService.java b/spring-core/src/main/java/com/baeldung/di/spring/IndexService.java new file mode 100644 index 0000000000..ad241f5200 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/IndexService.java @@ -0,0 +1,10 @@ +package com.baeldung.di.spring; + +public class IndexService implements IService { + + @Override + public String serve() { + return "Hello World"; + } + +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/InstanceServiceFactory.java b/spring-core/src/main/java/com/baeldung/di/spring/InstanceServiceFactory.java new file mode 100644 index 0000000000..f083504e8f --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/InstanceServiceFactory.java @@ -0,0 +1,14 @@ +package com.baeldung.di.spring; + +public class InstanceServiceFactory { + public IService getService(int number) { + switch (number) { + case 1: + return new MessageService("Foo"); + case 0: + return new IndexService(); + default: + throw new IllegalArgumentException("Unknown parameter " + number); + } + } +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/MessageApp.java b/spring-core/src/main/java/com/baeldung/di/spring/MessageApp.java new file mode 100644 index 0000000000..1bf6c20b28 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/MessageApp.java @@ -0,0 +1,14 @@ +package com.baeldung.di.spring; + +public class MessageApp { + + private IService iService; + + public MessageApp(IService iService) { + this.iService = iService; + } + + public String getServiceValue() { + return iService.serve(); + } +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/MessageService.java b/spring-core/src/main/java/com/baeldung/di/spring/MessageService.java new file mode 100644 index 0000000000..9b6efaab2a --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/MessageService.java @@ -0,0 +1,16 @@ +package com.baeldung.di.spring; + +public class MessageService implements IService { + + private String message; + + public MessageService(String message) { + this.message = message; + } + + @Override + public String serve() { + return message; + } + +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/StaticServiceFactory.java b/spring-core/src/main/java/com/baeldung/di/spring/StaticServiceFactory.java new file mode 100644 index 0000000000..bd70898faf --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/StaticServiceFactory.java @@ -0,0 +1,14 @@ +package com.baeldung.di.spring; + +public class StaticServiceFactory { + public static IService getService(int number) { + switch (number) { + case 1: + return new MessageService("Foo"); + case 0: + return new IndexService(); + default: + throw new IllegalArgumentException("Unknown parameter " + number); + } + } +} diff --git a/spring-core/src/main/resources/com.baeldung.di.spring.properties b/spring-core/src/main/resources/com.baeldung.di.spring.properties new file mode 100644 index 0000000000..8b8b5b85c2 --- /dev/null +++ b/spring-core/src/main/resources/com.baeldung.di.spring.properties @@ -0,0 +1 @@ +message.value=Hello World \ No newline at end of file diff --git a/spring-core/src/main/resources/com.baeldung.di.spring.xml b/spring-core/src/main/resources/com.baeldung.di.spring.xml new file mode 100644 index 0000000000..e0c5d22abb --- /dev/null +++ b/spring-core/src/main/resources/com.baeldung.di.spring.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-core/src/main/resources/dependencyinjectiontypes-context.xml b/spring-core/src/main/resources/dependencyinjectiontypes-context.xml new file mode 100644 index 0000000000..bd6b3c408d --- /dev/null +++ b/spring-core/src/main/resources/dependencyinjectiontypes-context.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-core/src/test/java/com/baeldung/dependencyinjectiontypes/DependencyInjectionTest.java b/spring-core/src/test/java/com/baeldung/dependencyinjectiontypes/DependencyInjectionTest.java new file mode 100644 index 0000000000..57c1927e58 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/dependencyinjectiontypes/DependencyInjectionTest.java @@ -0,0 +1,35 @@ +package com.baeldung.dependencyinjectiontypes; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class DependencyInjectionTest { + + @Test + public void givenAutowiredAnnotation_WhenSetOnSetter_ThenDependencyValid() { + + ApplicationContext context = new ClassPathXmlApplicationContext("dependencyinjectiontypes-context.xml"); + ArticleWithSetterInjection article = (ArticleWithSetterInjection) context.getBean("articleWithSetterInjectionBean"); + + String originalText = "This is a text !"; + String formattedArticle = article.format(originalText); + + assertTrue(originalText.toUpperCase().equals(formattedArticle)); + } + + @Test + public void givenAutowiredAnnotation_WhenSetOnConstructor_ThenDependencyValid() { + + ApplicationContext context = new ClassPathXmlApplicationContext("dependencyinjectiontypes-context.xml"); + ArticleWithConstructorInjection article = (ArticleWithConstructorInjection) context.getBean("articleWithConstructorInjectionBean"); + + String originalText = "This is a text !"; + String formattedArticle = article.format(originalText); + + assertTrue(originalText.toUpperCase().equals(formattedArticle)); + } + +} diff --git a/spring-core/src/test/java/com/baeldung/di/spring/BeanInjectionTest.java b/spring-core/src/test/java/com/baeldung/di/spring/BeanInjectionTest.java new file mode 100644 index 0000000000..1660b99726 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/di/spring/BeanInjectionTest.java @@ -0,0 +1,31 @@ +package com.baeldung.di.spring; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class BeanInjectionTest { + + private ApplicationContext applicationContext; + + @Before + public void setUp() throws Exception { + applicationContext = new ClassPathXmlApplicationContext("com.baeldung.di.spring.xml"); + } + + @Test + public void singletonBean_getBean_returnsSingleInstance() { + final IndexApp indexApp1 = applicationContext.getBean("indexApp", IndexApp.class); + final IndexApp indexApp2 = applicationContext.getBean("indexApp", IndexApp.class); + assertEquals(indexApp1, indexApp2); + } + + @Test + public void getBean_returnsInstance() { + final IndexApp indexApp = applicationContext.getBean("indexApp", IndexApp.class); + assertNotNull(indexApp); + } + +} diff --git a/spring-cucumber/src/main/java/com/baeldung/BaeldungController.java b/spring-cucumber/src/main/java/com/baeldung/BaeldungController.java index 8e87ed3028..e74e773106 100644 --- a/spring-cucumber/src/main/java/com/baeldung/BaeldungController.java +++ b/spring-cucumber/src/main/java/com/baeldung/BaeldungController.java @@ -1,22 +1,21 @@ package com.baeldung; -import javax.servlet.http.HttpServletResponse; - -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; +import javax.servlet.http.HttpServletResponse; + @RestController public class BaeldungController { - @RequestMapping(method = { RequestMethod.GET }, value = { "/hello" }) + @GetMapping("/hello") public String sayHello(HttpServletResponse response) { return "hello"; } - @RequestMapping(method = { RequestMethod.POST }, value = { "/baeldung" }) + @PostMapping("/baeldung") public String sayHelloPost(HttpServletResponse response) { return "hello"; } - } diff --git a/spring-cucumber/src/main/java/com/baeldung/SpringDemoApplication.java b/spring-cucumber/src/main/java/com/baeldung/SpringDemoApplication.java index 820e7e8004..ff9b12ad85 100644 --- a/spring-cucumber/src/main/java/com/baeldung/SpringDemoApplication.java +++ b/spring-cucumber/src/main/java/com/baeldung/SpringDemoApplication.java @@ -2,23 +2,16 @@ package com.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.web.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication -public class SpringDemoApplication extends SpringBootServletInitializer { +public class SpringDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringDemoApplication.class, args); } - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(SpringDemoApplication.class); - } - @Bean public RestTemplate getRestTemplate() { return new RestTemplate(); diff --git a/spring-cucumber/src/main/resources/application.properties b/spring-cucumber/src/main/resources/application.properties index e69de29bb2..8d51d0c619 100644 --- a/spring-cucumber/src/main/resources/application.properties +++ b/spring-cucumber/src/main/resources/application.properties @@ -0,0 +1 @@ +server.port=8082 \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/OtherDefsIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/OtherDefsIntegrationTest.java deleted file mode 100644 index 17f298c3fb..0000000000 --- a/spring-cucumber/src/test/java/com/baeldung/OtherDefsIntegrationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung; - -import cucumber.api.java.en.Given; -import cucumber.api.java.en.When; - -public class OtherDefsIntegrationTest extends SpringIntegrationTest { - @When("^the client calls /baeldung$") - public void the_client_issues_POST_hello() throws Throwable { - executePost("http://localhost:8080/baeldung"); - } - - @Given("^the client calls /hello$") - public void the_client_issues_GET_hello() throws Throwable { - executeGet("http://localhost:8080/hello"); - } -} \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/ResponseResults.java b/spring-cucumber/src/test/java/com/baeldung/ResponseResults.java index 4c0125e9b4..0f5bcbb824 100644 --- a/spring-cucumber/src/test/java/com/baeldung/ResponseResults.java +++ b/spring-cucumber/src/test/java/com/baeldung/ResponseResults.java @@ -11,23 +11,19 @@ public class ResponseResults { private final ClientHttpResponse theResponse; private final String body; - protected ResponseResults(final ClientHttpResponse response) throws IOException { + ResponseResults(final ClientHttpResponse response) throws IOException { this.theResponse = response; final InputStream bodyInputStream = response.getBody(); - if (null == bodyInputStream) { - this.body = "{}"; - } else { - final StringWriter stringWriter = new StringWriter(); - IOUtils.copy(bodyInputStream, stringWriter); - this.body = stringWriter.toString(); - } + final StringWriter stringWriter = new StringWriter(); + IOUtils.copy(bodyInputStream, stringWriter); + this.body = stringWriter.toString(); } - protected ClientHttpResponse getTheResponse() { + ClientHttpResponse getTheResponse() { return theResponse; } - protected String getBody() { + String getBody() { return body; } } \ No newline at end of file diff --git a/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java index 34efff63fb..9fbaeb348d 100644 --- a/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java +++ b/spring-cucumber/src/test/java/com/baeldung/SpringIntegrationTest.java @@ -1,9 +1,5 @@ package com.baeldung; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.IntegrationTest; import org.springframework.boot.test.SpringApplicationContextLoader; @@ -12,40 +8,39 @@ import org.springframework.http.client.ClientHttpResponse; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.web.client.ResponseErrorHandler; -import org.springframework.web.client.ResponseExtractor; import org.springframework.web.client.RestTemplate; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + //@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringDemoApplication.class, loader = SpringApplicationContextLoader.class) @WebAppConfiguration @IntegrationTest public class SpringIntegrationTest { - protected static ResponseResults latestResponse = null; + static ResponseResults latestResponse = null; @Autowired protected RestTemplate restTemplate; - protected void executeGet(String url) throws IOException { + void executeGet(String url) throws IOException { final Map headers = new HashMap<>(); headers.put("Accept", "application/json"); final HeaderSettingRequestCallback requestCallback = new HeaderSettingRequestCallback(headers); final ResponseResultErrorHandler errorHandler = new ResponseResultErrorHandler(); restTemplate.setErrorHandler(errorHandler); - latestResponse = restTemplate.execute(url, HttpMethod.GET, requestCallback, new ResponseExtractor() { - @Override - public ResponseResults extractData(ClientHttpResponse response) throws IOException { - if (errorHandler.hadError) { - return (errorHandler.getResults()); - } else { - return (new ResponseResults(response)); - } + latestResponse = restTemplate.execute(url, HttpMethod.GET, requestCallback, response -> { + if (errorHandler.hadError) { + return (errorHandler.getResults()); + } else { + return (new ResponseResults(response)); } }); - } - protected void executePost(String url) throws IOException { + void executePost() throws IOException { final Map headers = new HashMap<>(); headers.put("Accept", "application/json"); final HeaderSettingRequestCallback requestCallback = new HeaderSettingRequestCallback(headers); @@ -56,17 +51,14 @@ public class SpringIntegrationTest { } restTemplate.setErrorHandler(errorHandler); - latestResponse = restTemplate.execute(url, HttpMethod.POST, requestCallback, new ResponseExtractor() { - @Override - public ResponseResults extractData(ClientHttpResponse response) throws IOException { - if (errorHandler.hadError) { - return (errorHandler.getResults()); - } else { - return (new ResponseResults(response)); - } - } - }); - + latestResponse = restTemplate + .execute("http://localhost:8082/baeldung", HttpMethod.POST, requestCallback, response -> { + if (errorHandler.hadError) { + return (errorHandler.getResults()); + } else { + return (new ResponseResults(response)); + } + }); } private class ResponseResultErrorHandler implements ResponseErrorHandler { diff --git a/spring-cucumber/src/test/java/com/baeldung/StepDefsIntegrationTest.java b/spring-cucumber/src/test/java/com/baeldung/StepDefsIntegrationTest.java index 8220d5e861..e1b6e370c7 100644 --- a/spring-cucumber/src/test/java/com/baeldung/StepDefsIntegrationTest.java +++ b/spring-cucumber/src/test/java/com/baeldung/StepDefsIntegrationTest.java @@ -3,6 +3,7 @@ package com.baeldung; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import cucumber.api.java.en.Given; import org.springframework.http.HttpStatus; import cucumber.api.java.en.And; @@ -11,9 +12,19 @@ import cucumber.api.java.en.When; public class StepDefsIntegrationTest extends SpringIntegrationTest { + @When("^the client calls /baeldung$") + public void the_client_issues_POST_hello() throws Throwable { + executePost(); + } + + @Given("^the client calls /hello$") + public void the_client_issues_GET_hello() throws Throwable { + executeGet("http://localhost:8082/hello"); + } + @When("^the client calls /version$") public void the_client_issues_GET_version() throws Throwable { - executeGet("http://localhost:8080/version"); + executeGet("http://localhost:8082/version"); } @Then("^the client receives status code of (\\d+)$") diff --git a/spring-drools/README.md b/spring-drools/README.md new file mode 100644 index 0000000000..00b35a4624 --- /dev/null +++ b/spring-drools/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Drools Spring Integration](http://www.baeldung.com/drools-spring-integration) diff --git a/spring-groovy/README.md b/spring-groovy/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/spring-groovy/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/spring-groovy/pom.xml b/spring-groovy/pom.xml index 59c7ba4a7c..9086369fa4 100644 --- a/spring-groovy/pom.xml +++ b/spring-groovy/pom.xml @@ -37,5 +37,38 @@ spring-integration-groovy 4.3.7.RELEASE + + org.codehaus.groovy + groovy-all + 2.4.12 + + + + + maven-compiler-plugin + 3.7.0 + + groovy-eclipse-compiler + true + 1.8 + 1.8 + ${project.build.sourceEncoding} + + + + org.codehaus.groovy + groovy-eclipse-compiler + 2.9.2-01 + + + org.codehaus.groovy + groovy-eclipse-batch + 2.4.3-01 + + + + + + diff --git a/spring-groovy/src/main/java/com/baeldug/groovyconfig/BandsBean.java b/spring-groovy/src/main/java/com/baeldug/groovyconfig/BandsBean.java new file mode 100644 index 0000000000..1deba5d2f6 --- /dev/null +++ b/spring-groovy/src/main/java/com/baeldug/groovyconfig/BandsBean.java @@ -0,0 +1,17 @@ +package com.baeldug.groovyconfig; + +import java.util.ArrayList; +import java.util.List; + +public class BandsBean { + + private List bandsList = new ArrayList<>(); + + public List getBandsList() { + return bandsList; + } + + public void setBandsList(List bandsList) { + this.bandsList = bandsList; + } +} diff --git a/spring-groovy/src/main/java/com/baeldug/groovyconfig/GroovyBeanConfig.groovy b/spring-groovy/src/main/java/com/baeldug/groovyconfig/GroovyBeanConfig.groovy new file mode 100644 index 0000000000..32a6fedff0 --- /dev/null +++ b/spring-groovy/src/main/java/com/baeldug/groovyconfig/GroovyBeanConfig.groovy @@ -0,0 +1,18 @@ +package com.baeldug.groovyconfig; + +beans { + javaPesronBean(JavaPersonBean) { + firstName = 'John' + lastName = 'Doe' + age ='32' + eyesColor = 'blue' + hairColor='black' + } + + bandsBean(BandsBean) { bean-> + bean.scope = "singleton" + bandsList=['Nirvana', 'Pearl Jam', 'Foo Fighters'] + } + + registerAlias("bandsBean","bands") +} diff --git a/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaBeanConfig.java b/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaBeanConfig.java new file mode 100644 index 0000000000..7c4238ae28 --- /dev/null +++ b/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaBeanConfig.java @@ -0,0 +1,21 @@ +package com.baeldug.groovyconfig; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class JavaBeanConfig { + + @Bean + public JavaPersonBean javaPerson() { + JavaPersonBean jPerson = new JavaPersonBean(); + jPerson.setFirstName("John"); + jPerson.setLastName("Doe"); + jPerson.setAge("31"); + jPerson.setEyesColor("green"); + jPerson.setHairColor("blond"); + + return jPerson; + } + +} diff --git a/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaPersonBean.java b/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaPersonBean.java new file mode 100644 index 0000000000..db988d4abf --- /dev/null +++ b/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaPersonBean.java @@ -0,0 +1,57 @@ +package com.baeldug.groovyconfig; + +public class JavaPersonBean { + + public String jj; + + private String firstName; + + private String lastName; + + private String age; + + private String eyesColor; + + private String hairColor; + + 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 getAge() { + return age; + } + + public void setAge(String age) { + this.age = age; + } + + public String getEyesColor() { + return eyesColor; + } + + public void setEyesColor(String eyesColor) { + this.eyesColor = eyesColor; + } + + public String getHairColor() { + return hairColor; + } + + public void setHairColor(String hairColor) { + this.hairColor = hairColor; + } + +} diff --git a/spring-groovy/src/main/resources/xml-bean-config.xml b/spring-groovy/src/main/resources/xml-bean-config.xml new file mode 100644 index 0000000000..3b880bbd70 --- /dev/null +++ b/spring-groovy/src/main/resources/xml-bean-config.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationTest.java b/spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationTest.java new file mode 100644 index 0000000000..91ca6dbfe9 --- /dev/null +++ b/spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationTest.java @@ -0,0 +1,50 @@ +package com.baeldug.groovyconfig; + +import static org.junit.Assert.assertEquals; + +import java.io.File; + +import org.junit.Test; +import org.springframework.context.support.GenericGroovyApplicationContext; + +public class GroovyConfigurationTest { + + private static final String FILE_NAME = "GroovyBeanConfig.groovy"; + private static final String FILE_PATH = "src/main/java/com/baeldug/groovyconfig/"; + + @Test + public void whenGroovyConfig_thenCorrectPerson() throws Exception { + + GenericGroovyApplicationContext ctx = new GenericGroovyApplicationContext(); + ctx.load("file:" + getPathPart() + FILE_NAME); + ctx.refresh(); + + JavaPersonBean j = ctx.getBean(JavaPersonBean.class); + + assertEquals("32", j.getAge()); + assertEquals("blue", j.getEyesColor()); + assertEquals("black", j.getHairColor()); + } + + @Test + public void whenGroovyConfig_thenCorrectListLength() throws Exception { + + GenericGroovyApplicationContext ctx = new GenericGroovyApplicationContext(); + ctx.load("file:" + getPathPart() + FILE_NAME); + ctx.refresh(); + + BandsBean bb = ctx.getBean(BandsBean.class); + + assertEquals(3, bb.getBandsList() + .size()); + } + + private String getPathPart() { + String pathPart = new File(".").getAbsolutePath(); + pathPart = pathPart.replace(".", ""); + pathPart = pathPart.replace("\\", "/"); + pathPart = pathPart + FILE_PATH; + + return pathPart; + } +} diff --git a/spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationTest.java b/spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationTest.java new file mode 100644 index 0000000000..2d9b1000ff --- /dev/null +++ b/spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationTest.java @@ -0,0 +1,24 @@ +package com.baeldug.groovyconfig; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class JavaConfigurationTest { + + @Test + public void whenJavaConfig_thenCorrectPerson() { + + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(JavaBeanConfig.class); + ctx.refresh(); + + JavaPersonBean j = ctx.getBean(JavaPersonBean.class); + + assertEquals("31", j.getAge()); + assertEquals("green", j.getEyesColor()); + assertEquals("blond", j.getHairColor()); + + } +} diff --git a/spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationTest.java b/spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationTest.java new file mode 100644 index 0000000000..3ee724207c --- /dev/null +++ b/spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationTest.java @@ -0,0 +1,23 @@ +package com.baeldug.groovyconfig; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class XmlConfigurationTest { + + @Test + public void whenXmlConfig_thenCorrectPerson() { + final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("xml-bean-config.xml"); + + JavaPersonBean j = (JavaPersonBean) applicationContext.getBean("JavaPersonBean"); + + assertEquals("30", j.getAge()); + assertEquals("brown", j.getEyesColor()); + assertEquals("brown", j.getHairColor()); + + } + +} diff --git a/spring-hibernate3/src/main/java/org/baeldung/spring/PersistenceConfigHibernate3.java b/spring-hibernate3/src/main/java/org/baeldung/spring/PersistenceConfigHibernate3.java new file mode 100644 index 0000000000..a128d8848c --- /dev/null +++ b/spring-hibernate3/src/main/java/org/baeldung/spring/PersistenceConfigHibernate3.java @@ -0,0 +1,81 @@ +package org.baeldung.spring; + +import java.util.Properties; + +import javax.sql.DataSource; + +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.hibernate.SessionFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.orm.hibernate3.HibernateTransactionManager; +import org.springframework.orm.hibernate3.LocalSessionFactoryBean; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import com.google.common.base.Preconditions; + +@Configuration +@EnableTransactionManagement +@PropertySource({ "classpath:persistence-h2.properties" }) +@ComponentScan({ "org.baeldung.persistence.dao", "org.baeldung.persistence.service" }) +public class PersistenceConfigHibernate3 { + + @Autowired + private Environment env; + + public PersistenceConfigHibernate3() { + super(); + } + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + Resource config = new ClassPathResource("exceptionDemo.cfg.xml"); + sessionFactory.setDataSource(dataSource()); + sessionFactory.setConfigLocation(config); + sessionFactory.setHibernateProperties(hibernateProperties()); + + return sessionFactory; + } + + @Bean + public DataSource dataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + @Autowired + public HibernateTransactionManager transactionManager(final SessionFactory sessionFactory) { + final HibernateTransactionManager txManager = new HibernateTransactionManager(); + txManager.setSessionFactory(sessionFactory); + + return txManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + final Properties hibernateProperties() { + final Properties hibernateProperties = new Properties(); + hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); + hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); + // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); + return hibernateProperties; + } + +} diff --git a/spring-hibernate3/src/test/java/org/baeldung/persistence/service/HibernateExceptionScen1MainIntegrationTest.java b/spring-hibernate3/src/test/java/org/baeldung/persistence/service/HibernateExceptionScen1MainIntegrationTest.java new file mode 100644 index 0000000000..d53c4445a8 --- /dev/null +++ b/spring-hibernate3/src/test/java/org/baeldung/persistence/service/HibernateExceptionScen1MainIntegrationTest.java @@ -0,0 +1,43 @@ +package org.baeldung.persistence.service; + +import java.util.List; + +import org.baeldung.persistence.model.Event; +import org.baeldung.spring.PersistenceConfigHibernate3; +import org.hamcrest.core.IsInstanceOf; +import org.hibernate.HibernateException; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfigHibernate3.class }, loader = AnnotationConfigContextLoader.class) +public class HibernateExceptionScen1MainIntegrationTest { + + @Autowired + EventService service; + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + @Test + public final void whenEntityIsCreated_thenNoExceptions() { + service.create(new Event("from LocalSessionFactoryBean")); + } + + @Test + @Ignore + public final void whenNoTransBoundToSession_thenException() { + expectedEx.expectCause(IsInstanceOf.instanceOf(HibernateException.class)); + expectedEx.expectMessage("No Hibernate Session bound to thread, " + + "and configuration does not allow creation " + + "of non-transactional one here"); + service.create(new Event("from LocalSessionFactoryBean")); + } +} diff --git a/spring-hibernate3/src/test/java/org/baeldung/persistence/service/HibernateExceptionScen2MainIntegrationTest.java b/spring-hibernate3/src/test/java/org/baeldung/persistence/service/HibernateExceptionScen2MainIntegrationTest.java new file mode 100644 index 0000000000..84cafe0536 --- /dev/null +++ b/spring-hibernate3/src/test/java/org/baeldung/persistence/service/HibernateExceptionScen2MainIntegrationTest.java @@ -0,0 +1,45 @@ +package org.baeldung.persistence.service; + +import java.util.List; + +import org.baeldung.persistence.model.Event; +import org.baeldung.spring.PersistenceConfig; +import org.hamcrest.core.IsInstanceOf; +import org.hibernate.HibernateException; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +public class HibernateExceptionScen2MainIntegrationTest { + + @Autowired + EventService service; + + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + @Test + public final void whenEntityIsCreated_thenNoExceptions() { + service.create(new Event("from AnnotationSessionFactoryBean")); + } + + @Test + @Ignore + public final void whenNoTransBoundToSession_thenException() { + expectedEx.expectCause(IsInstanceOf.instanceOf(HibernateException.class)); + expectedEx.expectMessage("No Hibernate Session bound to thread, " + + "and configuration does not allow creation " + + "of non-transactional one here"); + service.create(new Event("from AnnotationSessionFactoryBean")); + } + +} diff --git a/spring-hibernate5/src/main/resources/manytomany.cfg.xml b/spring-hibernate5/src/main/resources/manytomany.cfg.xml deleted file mode 100644 index 8a10fc1580..0000000000 --- a/spring-hibernate5/src/main/resources/manytomany.cfg.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - com.mysql.jdbc.Driver - - - buddhinisam123 - - - jdbc:mysql://localhost:3306/spring_hibernate_many_to_many - - - root - - - org.hibernate.dialect.MySQLDialect - - - thread - - true - - diff --git a/spring-jmeter-jenkins/.gitignore b/spring-jmeter-jenkins/.gitignore new file mode 100644 index 0000000000..2af7cefb0a --- /dev/null +++ b/spring-jmeter-jenkins/.gitignore @@ -0,0 +1,24 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ \ No newline at end of file diff --git a/spring-jmeter-jenkins/.mvn/wrapper/maven-wrapper.jar b/spring-jmeter-jenkins/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000..5fd4d5023f Binary files /dev/null and b/spring-jmeter-jenkins/.mvn/wrapper/maven-wrapper.jar differ diff --git a/spring-jmeter-jenkins/.mvn/wrapper/maven-wrapper.properties b/spring-jmeter-jenkins/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000..c954cec91c --- /dev/null +++ b/spring-jmeter-jenkins/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip diff --git a/spring-jmeter-jenkins/README.md b/spring-jmeter-jenkins/README.md new file mode 100644 index 0000000000..49c18122a2 --- /dev/null +++ b/spring-jmeter-jenkins/README.md @@ -0,0 +1,55 @@ +BASIC CRUD API with Spring Boot +================================ + +This is the code of a simple API for some CRUD operations realised for a seminar at [FGI](www.fgi-ud.org) using Spring Boot. + +### Demo +* API: The online version **is**/**will be** hosted here: https://fgi-tcheck.herokuapp.com +* Mobile version is also opensource and located here: https://github.com/valdesekamdem/tcheck-mobile + +### Features +#### Currently Implemented +* CRUD + * Student + +#### To DO +* Validations of input with: [Spring Data Rest Validators](http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/validation-chapter.html) + + +### Requirements + +- Maven +- JDK 8 +- MongoDB + +### Running + +To build and start the server simply type + +```bash +$ mvn clean install +$ mvn spring-boot:run -Dserver.port=8989 +``` + +### Available CRUD + +You can see what crud operation are available using curl: + +```bash +$ curl localhost:8080 +``` +You can view existing student objects with this command: + +```bash +$ curl localhost:8080/students +``` +Or create a new one via a POST: + +```bash +$ curl -X POST -H "Content-Type:application/json" -d '{ "firstName" : "Dassi", "lastName" : "Orleando", "phoneNumber": "+237 545454545", "email": "mymail@yahoo.fr" }' localhost:8080/students +``` + + +Now with default configurations it will be available at: [http://localhost:8080](http://localhost:8080) + +Enjoy it :) \ No newline at end of file diff --git a/spring-jmeter-jenkins/mvnw b/spring-jmeter-jenkins/mvnw new file mode 100755 index 0000000000..a1ba1bf554 --- /dev/null +++ b/spring-jmeter-jenkins/mvnw @@ -0,0 +1,233 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # + # Look for the Apple JDKs first to preserve the existing behaviour, and then look + # for the new JDKs provided by Oracle. + # + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then + # + # Oracle JDKs + # + export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then + # + # Apple JDKs + # + export JAVA_HOME=`/usr/libexec/java_home` + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + local basedir=$(pwd) + local wdir=$(pwd) + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + wdir=$(cd "$wdir/.."; pwd) + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} "$@" diff --git a/spring-jmeter-jenkins/mvnw.cmd b/spring-jmeter-jenkins/mvnw.cmd new file mode 100644 index 0000000000..2b934e89dd --- /dev/null +++ b/spring-jmeter-jenkins/mvnw.cmd @@ -0,0 +1,145 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%* + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% \ No newline at end of file diff --git a/spring-jmeter-jenkins/pom.xml b/spring-jmeter-jenkins/pom.xml new file mode 100644 index 0000000000..38b5f98e45 --- /dev/null +++ b/spring-jmeter-jenkins/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + spring-jmeter-jenkins + 0.0.1-SNAPSHOT + jar + + spring-jmeter-jenkins + Run and Show JMeter test with Jenkins + + + parent-boot-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-5 + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + org.springframework.boot + spring-boot-starter-data-rest + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-jmeter-jenkins/src/main/java/com/baeldung/SpringJMeterJenkinsApplication.java b/spring-jmeter-jenkins/src/main/java/com/baeldung/SpringJMeterJenkinsApplication.java new file mode 100644 index 0000000000..3bc1f64f41 --- /dev/null +++ b/spring-jmeter-jenkins/src/main/java/com/baeldung/SpringJMeterJenkinsApplication.java @@ -0,0 +1,13 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; + +@SpringBootApplication +@EnableMongoRepositories +public class SpringJMeterJenkinsApplication { + public static void main(String[] args) { + SpringApplication.run(SpringJMeterJenkinsApplication.class, args); + } +} diff --git a/spring-jmeter-jenkins/src/main/java/com/baeldung/domain/Student.java b/spring-jmeter-jenkins/src/main/java/com/baeldung/domain/Student.java new file mode 100644 index 0000000000..0f6150fc48 --- /dev/null +++ b/spring-jmeter-jenkins/src/main/java/com/baeldung/domain/Student.java @@ -0,0 +1,66 @@ +package com.baeldung.domain; + +import javax.validation.constraints.NotNull; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.io.Serializable; + +@Document(collection = "STUDENT") +public class Student implements Serializable { + + @Id + private String id; + @NotNull + private String firstName; + private String lastName; + @NotNull + private String phoneNumber; + private String email; + + public String 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 getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public String toString() { + return "Student{" + + "firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + ", phoneNumber='" + phoneNumber + '\'' + + ", email='" + email + '\'' + + '}'; + } +} diff --git a/spring-jmeter-jenkins/src/main/java/com/baeldung/repository/StudentRepository.java b/spring-jmeter-jenkins/src/main/java/com/baeldung/repository/StudentRepository.java new file mode 100644 index 0000000000..d0ca7d8510 --- /dev/null +++ b/spring-jmeter-jenkins/src/main/java/com/baeldung/repository/StudentRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.repository; + +import org.springframework.data.mongodb.repository.MongoRepository; +import com.baeldung.domain.Student; + +public interface StudentRepository extends MongoRepository { +} diff --git a/spring-jmeter-jenkins/src/main/resources/JMeter-Jenkins.jmx b/spring-jmeter-jenkins/src/main/resources/JMeter-Jenkins.jmx new file mode 100644 index 0000000000..49ce2dec1d --- /dev/null +++ b/spring-jmeter-jenkins/src/main/resources/JMeter-Jenkins.jmx @@ -0,0 +1,96 @@ + + + + + + false + false + + + + + + + + continue + + false + 1 + + 5 + 1 + 1507776008000 + 1507776008000 + false + + + + + + + + + localhost + 8989 + + + /students + GET + true + false + true + false + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + + + + + + + 10 + + + + + + + true + + + + diff --git a/spring-jmeter-jenkins/src/main/resources/application.properties b/spring-jmeter-jenkins/src/main/resources/application.properties new file mode 100644 index 0000000000..c7d86e14b0 --- /dev/null +++ b/spring-jmeter-jenkins/src/main/resources/application.properties @@ -0,0 +1,14 @@ +# the db host +spring.data.mongodb.host=localhost +# the connection port (defaults to 27107) +spring.data.mongodb.port=27017 +# The database's name +spring.data.mongodb.database=JMeter-Jenkins + +# Or this +# spring.data.mongodb.uri=mongodb://localhost/JMeter-Jenkins + +# spring.data.mongodb.username= +# spring.data.mongodb.password= + +spring.data.mongodb.repositories.enabled=true \ No newline at end of file diff --git a/spring-jmeter-jenkins/src/test/java/com/baeldung/SpringJMeterJenkinsApplicationIntegrationTest.java b/spring-jmeter-jenkins/src/test/java/com/baeldung/SpringJMeterJenkinsApplicationIntegrationTest.java new file mode 100644 index 0000000000..71eec9cf45 --- /dev/null +++ b/spring-jmeter-jenkins/src/test/java/com/baeldung/SpringJMeterJenkinsApplicationIntegrationTest.java @@ -0,0 +1,16 @@ +package com.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringJMeterJenkinsApplicationIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-jms/README.md b/spring-jms/README.md index 9093937f44..b942cc72a0 100644 --- a/spring-jms/README.md +++ b/spring-jms/README.md @@ -1,2 +1,2 @@ -###Relevant Articles: +### Relevant Articles: - [An Introduction To Spring JMS](http://www.baeldung.com/spring-jms) diff --git a/spring-jms/src/main/webapp/META-INF/MANIFEST.MF b/spring-jms/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..5e9495128c --- /dev/null +++ b/spring-jms/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/spring-ldap/README.md b/spring-ldap/README.md index f77572d982..e2517b9d4b 100644 --- a/spring-ldap/README.md +++ b/spring-ldap/README.md @@ -4,6 +4,7 @@ - [Spring LDAP Overview](http://www.baeldung.com/spring-ldap) - [Spring LDAP Example Project](http://www.baeldung.com/spring-ldap-overview/) +- [Guide to Spring Data LDAP](http://www.baeldung.com/spring-data-ldap) diff --git a/spring-mustache/README.md b/spring-mustache/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/spring-mustache/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/BeanA.java b/spring-mvc-java/src/main/java/com/baeldung/web/BeanA.java index 79fac724f7..60da29f354 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/web/BeanA.java +++ b/spring-mvc-java/src/main/java/com/baeldung/web/BeanA.java @@ -12,5 +12,4 @@ public class BeanA { public BeanA() { super(); } - } diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/BeanB.java b/spring-mvc-java/src/main/java/com/baeldung/web/BeanB.java index 05c9560a0c..9e713d59ab 100644 --- a/spring-mvc-java/src/main/java/com/baeldung/web/BeanB.java +++ b/spring-mvc-java/src/main/java/com/baeldung/web/BeanB.java @@ -8,5 +8,4 @@ public class BeanB { public BeanB() { super(); } - } diff --git a/spring-mvc-kotlin/README.md b/spring-mvc-kotlin/README.md new file mode 100644 index 0000000000..c9bb78b6d8 --- /dev/null +++ b/spring-mvc-kotlin/README.md @@ -0,0 +1,2 @@ +### Relevant articles +- [Spring MVC Setup with Kotlin](http://www.baeldung.com/spring-mvc-kotlin) diff --git a/spring-mvc-kotlin/pom.xml b/spring-mvc-kotlin/pom.xml index 264cf49817..2d1dac5e29 100644 --- a/spring-mvc-kotlin/pom.xml +++ b/spring-mvc-kotlin/pom.xml @@ -45,6 +45,12 @@ thymeleaf-spring4 3.0.7.RELEASE + + org.springframework + spring-test + 4.3.10.RELEASE + test + @@ -55,7 +61,12 @@ kotlin-maven-plugin org.jetbrains.kotlin 1.1.4 - + + + spring + + 1.8 + compile @@ -64,7 +75,6 @@ compile - test-compile test-compile @@ -73,6 +83,13 @@ + + + org.jetbrains.kotlin + kotlin-maven-allopen + 1.1.4-3 + + diff --git a/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/allopen/SimpleConfiguration.kt b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/allopen/SimpleConfiguration.kt new file mode 100644 index 0000000000..5d0a3e13bf --- /dev/null +++ b/spring-mvc-kotlin/src/main/kotlin/com/baeldung/kotlin/allopen/SimpleConfiguration.kt @@ -0,0 +1,7 @@ +package com.baeldung.kotlin.allopen + +import org.springframework.context.annotation.Configuration + +@Configuration +class SimpleConfiguration { +} \ No newline at end of file diff --git a/spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/allopen/SimpleConfigurationTest.kt b/spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/allopen/SimpleConfigurationTest.kt new file mode 100644 index 0000000000..65a60c7157 --- /dev/null +++ b/spring-mvc-kotlin/src/test/kotlin/com/baeldung/kotlin/allopen/SimpleConfigurationTest.kt @@ -0,0 +1,19 @@ +package com.baeldung.kotlin.allopen + +import org.junit.Test +import org.junit.runner.RunWith +import org.springframework.test.context.ContextConfiguration +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner +import org.springframework.test.context.support.AnnotationConfigContextLoader + +@RunWith(SpringJUnit4ClassRunner::class) +@ContextConfiguration( + loader = AnnotationConfigContextLoader::class, + classes = arrayOf(SimpleConfiguration::class)) +class SimpleConfigurationTest { + + @Test + fun contextLoads() { + } + +} \ No newline at end of file diff --git a/spring-mvc-simple/README.md b/spring-mvc-simple/README.md index ffb02c846a..197a22cbac 100644 --- a/spring-mvc-simple/README.md +++ b/spring-mvc-simple/README.md @@ -1,3 +1,4 @@ ## Relevant articles: - [HandlerAdapters in Spring MVC](http://www.baeldung.com/spring-mvc-handler-adapters) +- [Template Engines for Spring](http://www.baeldung.com/spring-template-engines) diff --git a/spring-mybatis/README.md b/spring-mybatis/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/spring-mybatis/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/spring-rest-angular/README.md b/spring-rest-angular/README.md index 21e5b46922..dcbbd048ba 100644 --- a/spring-rest-angular/README.md +++ b/spring-rest-angular/README.md @@ -1,4 +1,5 @@ ## Spring REST Angular Example Project ### Relevant Articles: -- [RequestBody and ResponseBody Annotations](http://www.baeldung.com/requestbody-and-responsebody-annotations) + +- [Spring’s RequestBody and ResponseBody Annotations](http://www.baeldung.com/spring-request-response-body) diff --git a/spring-rest-angular/pom.xml b/spring-rest-angular/pom.xml index 0562e3ad58..3fc429f626 100644 --- a/spring-rest-angular/pom.xml +++ b/spring-rest-angular/pom.xml @@ -5,7 +5,6 @@ 4.0.0 spring-rest-angular spring-rest-angular - com.baeldung 1.0 war diff --git a/spring-rest-angular/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-rest-angular/src/main/webapp/WEB-INF/jsp/index.jsp deleted file mode 100644 index f44034a849..0000000000 --- a/spring-rest-angular/src/main/webapp/WEB-INF/jsp/index.jsp +++ /dev/null @@ -1,64 +0,0 @@ -<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> -<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %> - - - - - Spring Secured Sockets - " rel="stylesheet"> - - - - - - - - - -

    Welcome!

    -
    -
    -

    Request Body Controller POST Example

    -
    - - - - - - - - - - - - -
    User:
    Password:
    - -
    -
    -
    - -
    -

    Response Body Controller POST Example

    -
    - - - - - - - - - - - - -
    User:
    Password:
    - -
    -
    -

    {response}

    -
    - - \ No newline at end of file diff --git a/spring-rest-angular/src/main/webapp/resources/scripts/app.js b/spring-rest-angular/src/main/webapp/resources/scripts/app.js deleted file mode 100644 index 0ff7421bfc..0000000000 --- a/spring-rest-angular/src/main/webapp/resources/scripts/app.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -var angularApp = angular.module('angularApp', ['ngRoute']); \ No newline at end of file diff --git a/spring-rest-angular/src/main/webapp/resources/scripts/controllers.js b/spring-rest-angular/src/main/webapp/resources/scripts/controllers.js deleted file mode 100644 index a9a7f41c2d..0000000000 --- a/spring-rest-angular/src/main/webapp/resources/scripts/controllers.js +++ /dev/null @@ -1,27 +0,0 @@ -angularApp - .controller('requestBody', function ($scope, Form) { - $scope.postForm = function (context) { - var userField = document.getElementById('userField'); - var passwordField = document.getElementById('passwordField'); - if (userField.value != '' && passwordField.value != '') { - Form.post(context, userField.value, - passwordField.value).then(function (v) { - - }); - } - }; - }) - - .controller('responseBody', function ($scope, Form) { - $scope.response = "RESPONSEBODY WILL SHOW HERE"; - $scope.postForm = function (context) { - var userField = document.getElementById('userField'); - var passwordField = document.getElementById('passwordField'); - if (userField.value != '' && passwordField.value != '') { - Form.post(context, userField.value, - passwordField.value).then(function (v) { - $scope.response = v; - }); - } - }; - }); \ No newline at end of file diff --git a/spring-rest-angular/src/main/webapp/resources/scripts/factory.js b/spring-rest-angular/src/main/webapp/resources/scripts/factory.js deleted file mode 100644 index df08e3ba8d..0000000000 --- a/spring-rest-angular/src/main/webapp/resources/scripts/factory.js +++ /dev/null @@ -1,17 +0,0 @@ -angularApp - .factory('Form', function ($http, $q) { - return { - post: function (context, username, password) { - var deferred = $q.defer(); - $http({ - method: 'POST', - url: context + '/authenticate', - headers: {'Content-Type': 'application/x-www-form-urlencoded'}, - data: $.param({username: username, password: password}) - }).then(function (response) { - deferred.resolve(response); - }); - return deferred.promise; - } - } - }); \ No newline at end of file diff --git a/spring-rest-angular/src/main/webapp/resources/vendor/angular/angular.min.js b/spring-rest-angular/src/main/webapp/resources/vendor/angular/angular.min.js deleted file mode 100644 index aa62c75a39..0000000000 --- a/spring-rest-angular/src/main/webapp/resources/vendor/angular/angular.min.js +++ /dev/null @@ -1,316 +0,0 @@ -/* - AngularJS v1.5.7 - (c) 2010-2016 Google, Inc. http://angularjs.org - License: MIT -*/ -(function(E){'use strict';function O(a){return function(){var b=arguments[0],d;d="["+(a?a+":":"")+b+"] http://errors.angularjs.org/1.5.7/"+(a?a+"/":"")+b;for(b=1;b").append(a).html();try{return a[0].nodeType===Na?M(d):d.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+M(b)})}catch(c){return M(d)}}function zc(a){try{return decodeURIComponent(a)}catch(b){}}function Ac(a){var b={};r((a||"").split("&"),function(a){var c,e,f;a&&(e=a=a.replace(/\+/g,"%20"),c=a.indexOf("="), --1!==c&&(e=a.substring(0,c),f=a.substring(c+1)),e=zc(e),x(e)&&(f=x(f)?zc(f):!0,sa.call(b,e)?J(b[e])?b[e].push(f):b[e]=[b[e],f]:b[e]=f))});return b}function Tb(a){var b=[];r(a,function(a,c){J(a)?r(a,function(a){b.push(ja(c,!0)+(!0===a?"":"="+ja(a,!0)))}):b.push(ja(c,!0)+(!0===a?"":"="+ja(a,!0)))});return b.length?b.join("&"):""}function qb(a){return ja(a,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function ja(a,b){return encodeURIComponent(a).replace(/%40/gi,"@").replace(/%3A/gi, -":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%20/g,b?"%20":"+")}function fe(a,b){var d,c,e=Oa.length;for(c=0;c/,">"));}b=b||[];b.unshift(["$provide",function(b){b.value("$rootElement",a)}]);d.debugInfoEnabled&&b.push(["$compileProvider",function(a){a.debugInfoEnabled(!0)}]);b.unshift("ng");c=db(b,d.strictDi);c.invoke(["$rootScope","$rootElement","$compile","$injector",function(a,b,d,c){a.$apply(function(){b.data("$injector",c);d(b)(a)})}]); -return c},e=/^NG_ENABLE_DEBUG_INFO!/,f=/^NG_DEFER_BOOTSTRAP!/;E&&e.test(E.name)&&(d.debugInfoEnabled=!0,E.name=E.name.replace(e,""));if(E&&!f.test(E.name))return c();E.name=E.name.replace(f,"");ea.resumeBootstrap=function(a){r(a,function(a){b.push(a)});return c()};z(ea.resumeDeferredBootstrap)&&ea.resumeDeferredBootstrap()}function he(){E.name="NG_ENABLE_DEBUG_INFO!"+E.name;E.location.reload()}function ie(a){a=ea.element(a).injector();if(!a)throw za("test");return a.get("$$testability")}function Cc(a, -b){b=b||"_";return a.replace(je,function(a,c){return(c?b:"")+a.toLowerCase()})}function ke(){var a;if(!Dc){var b=rb();(pa=w(b)?E.jQuery:b?E[b]:void 0)&&pa.fn.on?(B=pa,R(pa.fn,{scope:Pa.scope,isolateScope:Pa.isolateScope,controller:Pa.controller,injector:Pa.injector,inheritedData:Pa.inheritedData}),a=pa.cleanData,pa.cleanData=function(b){for(var c,e=0,f;null!=(f=b[e]);e++)(c=pa._data(f,"events"))&&c.$destroy&&pa(f).triggerHandler("$destroy");a(b)}):B=U;ea.element=B;Dc=!0}}function sb(a,b,d){if(!a)throw za("areq", -b||"?",d||"required");return a}function Qa(a,b,d){d&&J(a)&&(a=a[a.length-1]);sb(z(a),b,"not a function, got "+(a&&"object"===typeof a?a.constructor.name||"Object":typeof a));return a}function Ra(a,b){if("hasOwnProperty"===a)throw za("badname",b);}function Ec(a,b,d){if(!b)return a;b=b.split(".");for(var c,e=a,f=b.length,g=0;g")+c[2];for(c=c[0];c--;)d=d.lastChild;f=ab(f,d.childNodes);d=e.firstChild;d.textContent=""}else f.push(b.createTextNode(a));e.textContent="";e.innerHTML="";r(f,function(a){e.appendChild(a)}); -return e}function Pc(a,b){var d=a.parentNode;d&&d.replaceChild(b,a);b.appendChild(a)}function U(a){if(a instanceof U)return a;var b;F(a)&&(a=W(a),b=!0);if(!(this instanceof U)){if(b&&"<"!=a.charAt(0))throw Wb("nosel");return new U(a)}if(b){b=E.document;var d;a=(d=Of.exec(a))?[b.createElement(d[1])]:(d=Oc(a,b))?d.childNodes:[]}Qc(this,a)}function Xb(a){return a.cloneNode(!0)}function wb(a,b){b||fb(a);if(a.querySelectorAll)for(var d=a.querySelectorAll("*"),c=0,e=d.length;c=Ba?!1:"function"===typeof a&&/^(?:class\s|constructor\()/.test(Function.prototype.toString.call(a)+" ");return d?(c.unshift(null),new (Function.prototype.bind.apply(a,c))):a.apply(b,c)},instantiate:function(a,b,c){var d=J(a)?a[a.length-1]:a;a=e(a,b,c);a.unshift(null);return new (Function.prototype.bind.apply(d, -a))},get:d,annotate:db.$$annotate,has:function(b){return n.hasOwnProperty(b+"Provider")||a.hasOwnProperty(b)}}}b=!0===b;var k={},l=[],m=new Sa([],!0),n={$provide:{provider:d(c),factory:d(f),service:d(function(a,b){return f(a,["$injector",function(a){return a.instantiate(b)}])}),value:d(function(a,b){return f(a,da(b),!1)}),constant:d(function(a,b){Ra(a,"constant");n[a]=b;s[a]=b}),decorator:function(a,b){var c=p.get(a+"Provider"),d=c.$get;c.$get=function(){var a=I.invoke(d,c);return I.invoke(b,null, -{$delegate:a})}}}},p=n.$injector=h(n,function(a,b){ea.isString(b)&&l.push(b);throw Ha("unpr",l.join(" <- "));}),s={},V=h(s,function(a,b){var c=p.get(a+"Provider",b);return I.invoke(c.$get,c,void 0,a)}),I=V;n.$injectorProvider={$get:da(V)};var q=g(a),I=V.get("$injector");I.strictDi=b;r(q,function(a){a&&I.invoke(a)});return I}function Ye(){var a=!0;this.disableAutoScrolling=function(){a=!1};this.$get=["$window","$location","$rootScope",function(b,d,c){function e(a){var b=null;Array.prototype.some.call(a, -function(a){if("a"===ua(a))return b=a,!0});return b}function f(a){if(a){a.scrollIntoView();var c;c=g.yOffset;z(c)?c=c():Qb(c)?(c=c[0],c="fixed"!==b.getComputedStyle(c).position?0:c.getBoundingClientRect().bottom):S(c)||(c=0);c&&(a=a.getBoundingClientRect().top,b.scrollBy(0,a-c))}else b.scrollTo(0,0)}function g(a){a=F(a)?a:d.hash();var b;a?(b=h.getElementById(a))?f(b):(b=e(h.getElementsByName(a)))?f(b):"top"===a&&f(null):f(null)}var h=b.document;a&&c.$watch(function(){return d.hash()},function(a,b){a=== -b&&""===a||Qf(function(){c.$evalAsync(g)})});return g}]}function hb(a,b){if(!a&&!b)return"";if(!a)return b;if(!b)return a;J(a)&&(a=a.join(" "));J(b)&&(b=b.join(" "));return a+" "+b}function Zf(a){F(a)&&(a=a.split(" "));var b=T();r(a,function(a){a.length&&(b[a]=!0)});return b}function Ia(a){return H(a)?a:{}}function $f(a,b,d,c){function e(a){try{a.apply(null,ta.call(arguments,1))}finally{if(V--,0===V)for(;I.length;)try{I.pop()()}catch(b){d.error(b)}}}function f(){y=null;g();h()}function g(){q=P(); -q=w(q)?null:q;na(q,D)&&(q=D);D=q}function h(){if(v!==k.url()||K!==q)v=k.url(),K=q,r(L,function(a){a(k.url(),q)})}var k=this,l=a.location,m=a.history,n=a.setTimeout,p=a.clearTimeout,s={};k.isMock=!1;var V=0,I=[];k.$$completeOutstandingRequest=e;k.$$incOutstandingRequestCount=function(){V++};k.notifyWhenNoOutstandingRequests=function(a){0===V?a():I.push(a)};var q,K,v=l.href,u=b.find("base"),y=null,P=c.history?function(){try{return m.state}catch(a){}}:A;g();K=q;k.url=function(b,d,e){w(e)&&(e=null);l!== -a.location&&(l=a.location);m!==a.history&&(m=a.history);if(b){var f=K===e;if(v===b&&(!c.history||f))return k;var h=v&&Ja(v)===Ja(b);v=b;K=e;!c.history||h&&f?(h||(y=b),d?l.replace(b):h?(d=l,e=b.indexOf("#"),e=-1===e?"":b.substr(e),d.hash=e):l.href=b,l.href!==b&&(y=b)):(m[d?"replaceState":"pushState"](e,"",b),g(),K=q);y&&(y=b);return k}return y||l.href.replace(/%27/g,"'")};k.state=function(){return q};var L=[],C=!1,D=null;k.onUrlChange=function(b){if(!C){if(c.history)B(a).on("popstate",f);B(a).on("hashchange", -f);C=!0}L.push(b);return b};k.$$applicationDestroyed=function(){B(a).off("hashchange popstate",f)};k.$$checkUrlChange=h;k.baseHref=function(){var a=u.attr("href");return a?a.replace(/^(https?\:)?\/\/[^\/]*/,""):""};k.defer=function(a,b){var c;V++;c=n(function(){delete s[c];e(a)},b||0);s[c]=!0;return c};k.defer.cancel=function(a){return s[a]?(delete s[a],p(a),e(A),!0):!1}}function ef(){this.$get=["$window","$log","$sniffer","$document",function(a,b,d,c){return new $f(a,c,b,d)}]}function ff(){this.$get= -function(){function a(a,c){function e(a){a!=n&&(p?p==a&&(p=a.n):p=a,f(a.n,a.p),f(a,n),n=a,n.n=null)}function f(a,b){a!=b&&(a&&(a.p=b),b&&(b.n=a))}if(a in b)throw O("$cacheFactory")("iid",a);var g=0,h=R({},c,{id:a}),k=T(),l=c&&c.capacity||Number.MAX_VALUE,m=T(),n=null,p=null;return b[a]={put:function(a,b){if(!w(b)){if(ll&&this.remove(p.key);return b}},get:function(a){if(l";b=la.firstChild.attributes;var d=b[0];b.removeNamedItem(d.name);d.value=c;a.attributes.setNamedItem(d)}function N(a,b){try{a.addClass(b)}catch(c){}}function ba(a,b,c,d,e){a instanceof B||(a=B(a));for(var f=/\S+/,g=0,h=a.length;g< -h;g++){var k=a[g];k.nodeType===Na&&k.nodeValue.match(f)&&Pc(k,a[g]=E.document.createElement("span"))}var l=t(a,b,a,c,d,e);ba.$$addScopeClass(a);var n=null;return function(b,c,d){sb(b,"scope");e&&e.needsNewScope&&(b=b.$parent.$new());d=d||{};var f=d.parentBoundTranscludeFn,g=d.transcludeControllers;d=d.futureParentElement;f&&f.$$boundTransclude&&(f=f.$$boundTransclude);n||(n=(d=d&&d[0])?"foreignobject"!==ua(d)&&ka.call(d).match(/SVG/)?"svg":"html":"html");d="html"!==n?B(ca(n,B("
    ").append(a).html())): -c?Pa.clone.call(a):a;if(g)for(var h in g)d.data("$"+h+"Controller",g[h].instance);ba.$$addScopeInfo(d,b);c&&c(d,b);l&&l(b,d,d,f);return d}}function t(a,b,c,d,e,f){function g(a,c,d,e){var f,k,l,n,m,v,q;if(p)for(q=Array(c.length),n=0;nu.priority)break;if(x=u.scope)u.templateUrl||(H(x)?(X("new/isolated scope",s||v,u,N),s=u):X("new/isolated scope",s,u,N)),v=v||u;G=u.name;if(!Ca&&(u.replace&&(u.templateUrl||u.template)||u.transclude&&!u.$$tlb)){for(x=A+1;Ca=a[x++];)if(Ca.transclude&&!Ca.$$tlb||Ca.replace&& -(Ca.templateUrl||Ca.template)){wa=!0;break}Ca=!0}!u.templateUrl&&u.controller&&(x=u.controller,q=q||T(),X("'"+G+"' controller",q[G],u,N),q[G]=u);if(x=u.transclude)if(D=!0,u.$$tlb||(X("transclusion",C,u,N),C=u),"element"==x)y=!0,p=u.priority,Q=N,N=d.$$element=B(ba.$$createComment(G,d[G])),b=N[0],da(f,ta.call(Q,0),b),Q[0].$$parentNode=Q[0].parentNode,P=ac(wa,Q,e,p,g&&g.name,{nonTlbTranscludeDirective:C});else{var M=T();Q=B(Xb(b)).contents();if(H(x)){Q=[];var S=T(),Da=T();r(x,function(a,b){var c="?"=== -a.charAt(0);a=c?a.substring(1):a;S[a]=b;M[b]=null;Da[b]=c});r(N.contents(),function(a){var b=S[xa(ua(a))];b?(Da[b]=!0,M[b]=M[b]||[],M[b].push(a)):Q.push(a)});r(Da,function(a,b){if(!a)throw fa("reqslot",b);});for(var Y in M)M[Y]&&(M[Y]=ac(wa,M[Y],e))}N.empty();P=ac(wa,Q,e,void 0,void 0,{needsNewScope:u.$$isolateScope||u.$$newScope});P.$$slots=M}if(u.template)if(I=!0,X("template",L,u,N),L=u,x=z(u.template)?u.template(N,d):u.template,x=ra(x),u.replace){g=u;Q=Vb.test(x)?$c(ca(u.templateNamespace,W(x))): -[];b=Q[0];if(1!=Q.length||1!==b.nodeType)throw fa("tplrt",G,"");da(f,N,b);E={$attr:{}};x=$b(b,[],E);var aa=a.splice(A+1,a.length-(A+1));(s||v)&&ad(x,s,v);a=a.concat(x).concat(aa);U(d,E);E=a.length}else N.html(x);if(u.templateUrl)I=!0,X("template",L,u,N),L=u,u.replace&&(g=u),m=$(a.splice(A,a.length-A),N,d,f,D&&P,h,k,{controllerDirectives:q,newScopeDirective:v!==u&&v,newIsolateScopeDirective:s,templateDirective:L,nonTlbTranscludeDirective:C}),E=a.length;else if(u.compile)try{t=u.compile(N,d,P);var Z= -u.$$originalDirective||u;z(t)?n(null,bb(Z,t),F,Ta):t&&n(bb(Z,t.pre),bb(Z,t.post),F,Ta)}catch(ea){c(ea,va(N))}u.terminal&&(m.terminal=!0,p=Math.max(p,u.priority))}m.scope=v&&!0===v.scope;m.transcludeOnThisElement=D;m.templateOnThisElement=I;m.transclude=P;l.hasElementTranscludeDirective=y;return m}function ib(a,b,c,d){var e;if(F(b)){var f=b.match(l);b=b.substring(f[0].length);var g=f[1]||f[3],f="?"===f[2];"^^"===g?c=c.parent():e=(e=d&&d[b])&&e.instance;if(!e){var h="$"+b+"Controller";e=g?c.inheritedData(h): -c.data(h)}if(!e&&!f)throw fa("ctreq",b,a);}else if(J(b))for(e=[],g=0,f=b.length;gm.priority)&&-1!=m.restrict.indexOf(g)){l&&(m=Rb(m,{$$start:l,$$end:n}));if(!m.$$bindings){var q=m,s=m,L=m.name,u={isolateScope:null,bindToController:null};H(s.scope)&&(!0===s.bindToController?(u.bindToController=d(s.scope,L,!0),u.isolateScope={}):u.isolateScope=d(s.scope,L,!1));H(s.bindToController)&&(u.bindToController= -d(s.bindToController,L,!0));if(H(u.bindToController)){var C=s.controller,D=s.controllerAs;if(!C)throw fa("noctrl",L);if(!Xc(C,D))throw fa("noident",L);}var N=q.$$bindings=u;H(N.isolateScope)&&(m.$$isolateBindings=N.isolateScope)}b.push(m);k=m}}catch(G){c(G)}}return k}function S(b){if(f.hasOwnProperty(b))for(var c=a.get(b+"Directive"),d=0,e=c.length;d"+b+"";return c.childNodes[0].childNodes;default:return b}}function ea(a,b){if("srcdoc"==b)return L.HTML;var c=ua(a);if("xlinkHref"==b||"form"==c&&"action"==b||"img"!=c&&("src"==b||"ngSrc"==b))return L.RESOURCE_URL}function ia(a, -c,d,e,f){var g=ea(a,e);f=k[e]||f;var h=b(d,!0,g,f);if(h){if("multiple"===e&&"select"===ua(a))throw fa("selmulti",va(a));c.push({priority:100,compile:function(){return{pre:function(a,c,k){c=k.$$observers||(k.$$observers=T());if(m.test(e))throw fa("nodomevents");var l=k[e];l!==d&&(h=l&&b(l,!0,g,f),d=l);h&&(k[e]=h(a),(c[e]||(c[e]=[])).$$inter=!0,(k.$$observers&&k.$$observers[e].$$scope||a).$watch(h,function(a,b){"class"===e&&a!=b?k.$updateClass(a,b):k.$set(e,a)}))}}}})}}function da(a,b,c){var d=b[0], -e=b.length,f=d.parentNode,g,h;if(a)for(g=0,h=a.length;g=b)return a;for(;b--;)8===a[b].nodeType&&bg.call(a,b,1);return a}function Xc(a,b){if(b&&F(b))return b;if(F(a)){var d=dd.exec(a);if(d)return d[3]}}function gf(){var a={},b=!1;this.has=function(b){return a.hasOwnProperty(b)};this.register=function(b,c){Ra(b,"controller");H(b)?R(a,b):a[b]=c};this.allowGlobals=function(){b=!0};this.$get=["$injector","$window",function(d,c){function e(a, -b,c,d){if(!a||!H(a.$scope))throw O("$controller")("noscp",d,b);a.$scope[b]=c}return function(f,g,h,k){var l,m,n;h=!0===h;k&&F(k)&&(n=k);if(F(f)){k=f.match(dd);if(!k)throw cg("ctrlfmt",f);m=k[1];n=n||k[3];f=a.hasOwnProperty(m)?a[m]:Ec(g.$scope,m,!0)||(b?Ec(c,m,!0):void 0);Qa(f,m,!0)}if(h)return h=(J(f)?f[f.length-1]:f).prototype,l=Object.create(h||null),n&&e(g,n,l,m||f.name),R(function(){var a=d.invoke(f,l,g,m);a!==l&&(H(a)||z(a))&&(l=a,n&&e(g,n,l,m||f.name));return l},{instance:l,identifier:n});l= -d.instantiate(f,g,m);n&&e(g,n,l,m||f.name);return l}}]}function hf(){this.$get=["$window",function(a){return B(a.document)}]}function jf(){this.$get=["$log",function(a){return function(b,d){a.error.apply(a,arguments)}}]}function cc(a){return H(a)?ia(a)?a.toISOString():cb(a):a}function of(){this.$get=function(){return function(a){if(!a)return"";var b=[];tc(a,function(a,c){null===a||w(a)||(J(a)?r(a,function(a){b.push(ja(c)+"="+ja(cc(a)))}):b.push(ja(c)+"="+ja(cc(a))))});return b.join("&")}}}function pf(){this.$get= -function(){return function(a){function b(a,e,f){null===a||w(a)||(J(a)?r(a,function(a,c){b(a,e+"["+(H(a)?c:"")+"]")}):H(a)&&!ia(a)?tc(a,function(a,c){b(a,e+(f?"":"[")+c+(f?"":"]"))}):d.push(ja(e)+"="+ja(cc(a))))}if(!a)return"";var d=[];b(a,"",!0);return d.join("&")}}}function dc(a,b){if(F(a)){var d=a.replace(dg,"").trim();if(d){var c=b("Content-Type");(c=c&&0===c.indexOf(ed))||(c=(c=d.match(eg))&&fg[c[0]].test(d));c&&(a=xc(d))}}return a}function fd(a){var b=T(),d;F(a)?r(a.split("\n"),function(a){d= -a.indexOf(":");var e=M(W(a.substr(0,d)));a=W(a.substr(d+1));e&&(b[e]=b[e]?b[e]+", "+a:a)}):H(a)&&r(a,function(a,d){var f=M(d),g=W(a);f&&(b[f]=b[f]?b[f]+", "+g:g)});return b}function gd(a){var b;return function(d){b||(b=fd(a));return d?(d=b[M(d)],void 0===d&&(d=null),d):b}}function hd(a,b,d,c){if(z(c))return c(a,b,d);r(c,function(c){a=c(a,b,d)});return a}function nf(){var a=this.defaults={transformResponse:[dc],transformRequest:[function(a){return H(a)&&"[object File]"!==ka.call(a)&&"[object Blob]"!== -ka.call(a)&&"[object FormData]"!==ka.call(a)?cb(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"},post:ga(ec),put:ga(ec),patch:ga(ec)},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",paramSerializer:"$httpParamSerializer"},b=!1;this.useApplyAsync=function(a){return x(a)?(b=!!a,this):b};var d=!0;this.useLegacyPromiseExtensions=function(a){return x(a)?(d=!!a,this):d};var c=this.interceptors=[];this.$get=["$httpBackend","$$cookieReader","$cacheFactory","$rootScope","$q","$injector", -function(e,f,g,h,k,l){function m(b){function c(a){var b=R({},a);b.data=hd(a.data,a.headers,a.status,f.transformResponse);a=a.status;return 200<=a&&300>a?b:k.reject(b)}function e(a,b){var c,d={};r(a,function(a,e){z(a)?(c=a(b),null!=c&&(d[e]=c)):d[e]=a});return d}if(!H(b))throw O("$http")("badreq",b);if(!F(b.url))throw O("$http")("badreq",b.url);var f=R({method:"get",transformRequest:a.transformRequest,transformResponse:a.transformResponse,paramSerializer:a.paramSerializer},b);f.headers=function(b){var c= -a.headers,d=R({},b.headers),f,g,h,c=R({},c.common,c[M(b.method)]);a:for(f in c){g=M(f);for(h in d)if(M(h)===g)continue a;d[f]=c[f]}return e(d,ga(b))}(b);f.method=ub(f.method);f.paramSerializer=F(f.paramSerializer)?l.get(f.paramSerializer):f.paramSerializer;var g=[function(b){var d=b.headers,e=hd(b.data,gd(d),void 0,b.transformRequest);w(e)&&r(d,function(a,b){"content-type"===M(b)&&delete d[b]});w(b.withCredentials)&&!w(a.withCredentials)&&(b.withCredentials=a.withCredentials);return n(b,e).then(c, -c)},void 0],h=k.when(f);for(r(V,function(a){(a.request||a.requestError)&&g.unshift(a.request,a.requestError);(a.response||a.responseError)&&g.push(a.response,a.responseError)});g.length;){b=g.shift();var m=g.shift(),h=h.then(b,m)}d?(h.success=function(a){Qa(a,"fn");h.then(function(b){a(b.data,b.status,b.headers,f)});return h},h.error=function(a){Qa(a,"fn");h.then(null,function(b){a(b.data,b.status,b.headers,f)});return h}):(h.success=id("success"),h.error=id("error"));return h}function n(c,d){function g(a){if(a){var c= -{};r(a,function(a,d){c[d]=function(c){function d(){a(c)}b?h.$applyAsync(d):h.$$phase?d():h.$apply(d)}});return c}}function l(a,c,d,e){function f(){n(c,a,d,e)}D&&(200<=a&&300>a?D.put(Q,[a,c,fd(d),e]):D.remove(Q));b?h.$applyAsync(f):(f(),h.$$phase||h.$apply())}function n(a,b,d,e){b=-1<=b?b:0;(200<=b&&300>b?L.resolve:L.reject)({data:a,status:b,headers:gd(d),config:c,statusText:e})}function y(a){n(a.data,a.status,ga(a.headers()),a.statusText)}function V(){var a=m.pendingRequests.indexOf(c);-1!==a&&m.pendingRequests.splice(a, -1)}var L=k.defer(),C=L.promise,D,G,Aa=c.headers,Q=p(c.url,c.paramSerializer(c.params));m.pendingRequests.push(c);C.then(V,V);!c.cache&&!a.cache||!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method||(D=H(c.cache)?c.cache:H(a.cache)?a.cache:s);D&&(G=D.get(Q),x(G)?G&&z(G.then)?G.then(y,y):J(G)?n(G[1],G[0],ga(G[2]),G[3]):n(G,200,{},"OK"):D.put(Q,C));w(G)&&((G=jd(c.url)?f()[c.xsrfCookieName||a.xsrfCookieName]:void 0)&&(Aa[c.xsrfHeaderName||a.xsrfHeaderName]=G),e(c.method,Q,d,l,Aa,c.timeout,c.withCredentials, -c.responseType,g(c.eventHandlers),g(c.uploadEventHandlers)));return C}function p(a,b){0=l&&(v.resolve(q),I(u.$$intervalId),delete g[u.$$intervalId]);K||a.$apply()},k);g[u.$$intervalId]=v;return u}var g={};f.cancel=function(a){return a&&a.$$intervalId in g?(g[a.$$intervalId].reject("canceled"),b.clearInterval(a.$$intervalId),delete g[a.$$intervalId],!0):!1};return f}]}function fc(a){a=a.split("/");for(var b=a.length;b--;)a[b]= -qb(a[b]);return a.join("/")}function kd(a,b){var d=qa(a);b.$$protocol=d.protocol;b.$$host=d.hostname;b.$$port=aa(d.port)||hg[d.protocol]||null}function ld(a,b){var d="/"!==a.charAt(0);d&&(a="/"+a);var c=qa(a);b.$$path=decodeURIComponent(d&&"/"===c.pathname.charAt(0)?c.pathname.substring(1):c.pathname);b.$$search=Ac(c.search);b.$$hash=decodeURIComponent(c.hash);b.$$path&&"/"!=b.$$path.charAt(0)&&(b.$$path="/"+b.$$path)}function la(a,b){if(0===b.lastIndexOf(a,0))return b.substr(a.length)}function Ja(a){var b= -a.indexOf("#");return-1==b?a:a.substr(0,b)}function jb(a){return a.replace(/(#.+)|#$/,"$1")}function gc(a,b,d){this.$$html5=!0;d=d||"";kd(a,this);this.$$parse=function(a){var d=la(b,a);if(!F(d))throw Gb("ipthprfx",a,b);ld(d,this);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Tb(this.$$search),d=this.$$hash?"#"+qb(this.$$hash):"";this.$$url=fc(this.$$path)+(a?"?"+a:"")+d;this.$$absUrl=b+this.$$url.substr(1)};this.$$parseLinkUrl=function(c,e){if(e&&"#"===e[0])return this.hash(e.slice(1)), -!0;var f,g;x(f=la(a,c))?(g=f,g=x(f=la(d,f))?b+(la("/",f)||f):a+g):x(f=la(b,c))?g=b+f:b==c+"/"&&(g=b);g&&this.$$parse(g);return!!g}}function hc(a,b,d){kd(a,this);this.$$parse=function(c){var e=la(a,c)||la(b,c),f;w(e)||"#"!==e.charAt(0)?this.$$html5?f=e:(f="",w(e)&&(a=c,this.replace())):(f=la(d,e),w(f)&&(f=e));ld(f,this);c=this.$$path;var e=a,g=/^\/[A-Z]:(\/.*)/;0===f.lastIndexOf(e,0)&&(f=f.replace(e,""));g.exec(f)||(c=(f=g.exec(c))?f[1]:c);this.$$path=c;this.$$compose()};this.$$compose=function(){var b= -Tb(this.$$search),e=this.$$hash?"#"+qb(this.$$hash):"";this.$$url=fc(this.$$path)+(b?"?"+b:"")+e;this.$$absUrl=a+(this.$$url?d+this.$$url:"")};this.$$parseLinkUrl=function(b,d){return Ja(a)==Ja(b)?(this.$$parse(b),!0):!1}}function md(a,b,d){this.$$html5=!0;hc.apply(this,arguments);this.$$parseLinkUrl=function(c,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;a==Ja(c)?f=c:(g=la(b,c))?f=a+d+g:b===c+"/"&&(f=b);f&&this.$$parse(f);return!!f};this.$$compose=function(){var b=Tb(this.$$search), -e=this.$$hash?"#"+qb(this.$$hash):"";this.$$url=fc(this.$$path)+(b?"?"+b:"")+e;this.$$absUrl=a+d+this.$$url}}function Hb(a){return function(){return this[a]}}function nd(a,b){return function(d){if(w(d))return this[a];this[a]=b(d);this.$$compose();return this}}function sf(){var a="",b={enabled:!1,requireBase:!0,rewriteLinks:!0};this.hashPrefix=function(b){return x(b)?(a=b,this):a};this.html5Mode=function(a){return Ea(a)?(b.enabled=a,this):H(a)?(Ea(a.enabled)&&(b.enabled=a.enabled),Ea(a.requireBase)&& -(b.requireBase=a.requireBase),Ea(a.rewriteLinks)&&(b.rewriteLinks=a.rewriteLinks),this):b};this.$get=["$rootScope","$browser","$sniffer","$rootElement","$window",function(d,c,e,f,g){function h(a,b,d){var e=l.url(),f=l.$$state;try{c.url(a,b,d),l.$$state=c.state()}catch(g){throw l.url(e),l.$$state=f,g;}}function k(a,b){d.$broadcast("$locationChangeSuccess",l.absUrl(),a,l.$$state,b)}var l,m;m=c.baseHref();var n=c.url(),p;if(b.enabled){if(!m&&b.requireBase)throw Gb("nobase");p=n.substring(0,n.indexOf("/", -n.indexOf("//")+2))+(m||"/");m=e.history?gc:md}else p=Ja(n),m=hc;var s=p.substr(0,Ja(p).lastIndexOf("/")+1);l=new m(p,s,"#"+a);l.$$parseLinkUrl(n,n);l.$$state=c.state();var r=/^\s*(javascript|mailto):/i;f.on("click",function(a){if(b.rewriteLinks&&!a.ctrlKey&&!a.metaKey&&!a.shiftKey&&2!=a.which&&2!=a.button){for(var e=B(a.target);"a"!==ua(e[0]);)if(e[0]===f[0]||!(e=e.parent())[0])return;var h=e.prop("href"),k=e.attr("href")||e.attr("xlink:href");H(h)&&"[object SVGAnimatedString]"===h.toString()&&(h= -qa(h.animVal).href);r.test(h)||!h||e.attr("target")||a.isDefaultPrevented()||!l.$$parseLinkUrl(h,k)||(a.preventDefault(),l.absUrl()!=c.url()&&(d.$apply(),g.angular["ff-684208-preventDefault"]=!0))}});jb(l.absUrl())!=jb(n)&&c.url(l.absUrl(),!0);var I=!0;c.onUrlChange(function(a,b){w(la(s,a))?g.location.href=a:(d.$evalAsync(function(){var c=l.absUrl(),e=l.$$state,f;a=jb(a);l.$$parse(a);l.$$state=b;f=d.$broadcast("$locationChangeStart",a,c,b,e).defaultPrevented;l.absUrl()===a&&(f?(l.$$parse(c),l.$$state= -e,h(c,!1,e)):(I=!1,k(c,e)))}),d.$$phase||d.$digest())});d.$watch(function(){var a=jb(c.url()),b=jb(l.absUrl()),f=c.state(),g=l.$$replace,n=a!==b||l.$$html5&&e.history&&f!==l.$$state;if(I||n)I=!1,d.$evalAsync(function(){var b=l.absUrl(),c=d.$broadcast("$locationChangeStart",b,a,l.$$state,f).defaultPrevented;l.absUrl()===b&&(c?(l.$$parse(a),l.$$state=f):(n&&h(b,g,f===l.$$state?null:l.$$state),k(a,f)))});l.$$replace=!1});return l}]}function tf(){var a=!0,b=this;this.debugEnabled=function(b){return x(b)? -(a=b,this):a};this.$get=["$window",function(d){function c(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=d.console||{},e=b[a]||b.log||A;a=!1;try{a=!!e.apply}catch(k){}return a?function(){var a=[];r(arguments,function(b){a.push(c(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"), -debug:function(){var c=e("debug");return function(){a&&c.apply(b,arguments)}}()}}]}function Ua(a,b){if("__defineGetter__"===a||"__defineSetter__"===a||"__lookupGetter__"===a||"__lookupSetter__"===a||"__proto__"===a)throw ca("isecfld",b);return a}function ig(a){return a+""}function ra(a,b){if(a){if(a.constructor===a)throw ca("isecfn",b);if(a.window===a)throw ca("isecwindow",b);if(a.children&&(a.nodeName||a.prop&&a.attr&&a.find))throw ca("isecdom",b);if(a===Object)throw ca("isecobj",b);}return a}function od(a, -b){if(a){if(a.constructor===a)throw ca("isecfn",b);if(a===jg||a===kg||a===lg)throw ca("isecff",b);}}function Ib(a,b){if(a&&(a===(0).constructor||a===(!1).constructor||a==="".constructor||a==={}.constructor||a===[].constructor||a===Function.constructor))throw ca("isecaf",b);}function mg(a,b){return"undefined"!==typeof a?a:b}function pd(a,b){return"undefined"===typeof a?b:"undefined"===typeof b?a:a+b}function $(a,b){var d,c;switch(a.type){case t.Program:d=!0;r(a.body,function(a){$(a.expression,b);d= -d&&a.expression.constant});a.constant=d;break;case t.Literal:a.constant=!0;a.toWatch=[];break;case t.UnaryExpression:$(a.argument,b);a.constant=a.argument.constant;a.toWatch=a.argument.toWatch;break;case t.BinaryExpression:$(a.left,b);$(a.right,b);a.constant=a.left.constant&&a.right.constant;a.toWatch=a.left.toWatch.concat(a.right.toWatch);break;case t.LogicalExpression:$(a.left,b);$(a.right,b);a.constant=a.left.constant&&a.right.constant;a.toWatch=a.constant?[]:[a];break;case t.ConditionalExpression:$(a.test, -b);$(a.alternate,b);$(a.consequent,b);a.constant=a.test.constant&&a.alternate.constant&&a.consequent.constant;a.toWatch=a.constant?[]:[a];break;case t.Identifier:a.constant=!1;a.toWatch=[a];break;case t.MemberExpression:$(a.object,b);a.computed&&$(a.property,b);a.constant=a.object.constant&&(!a.computed||a.property.constant);a.toWatch=[a];break;case t.CallExpression:d=a.filter?!b(a.callee.name).$stateful:!1;c=[];r(a.arguments,function(a){$(a,b);d=d&&a.constant;a.constant||c.push.apply(c,a.toWatch)}); -a.constant=d;a.toWatch=a.filter&&!b(a.callee.name).$stateful?c:[a];break;case t.AssignmentExpression:$(a.left,b);$(a.right,b);a.constant=a.left.constant&&a.right.constant;a.toWatch=[a];break;case t.ArrayExpression:d=!0;c=[];r(a.elements,function(a){$(a,b);d=d&&a.constant;a.constant||c.push.apply(c,a.toWatch)});a.constant=d;a.toWatch=c;break;case t.ObjectExpression:d=!0;c=[];r(a.properties,function(a){$(a.value,b);d=d&&a.value.constant&&!a.computed;a.value.constant||c.push.apply(c,a.value.toWatch)}); -a.constant=d;a.toWatch=c;break;case t.ThisExpression:a.constant=!1;a.toWatch=[];break;case t.LocalsExpression:a.constant=!1,a.toWatch=[]}}function qd(a){if(1==a.length){a=a[0].expression;var b=a.toWatch;return 1!==b.length?b:b[0]!==a?b:void 0}}function rd(a){return a.type===t.Identifier||a.type===t.MemberExpression}function sd(a){if(1===a.body.length&&rd(a.body[0].expression))return{type:t.AssignmentExpression,left:a.body[0].expression,right:{type:t.NGValueParameter},operator:"="}}function td(a){return 0=== -a.body.length||1===a.body.length&&(a.body[0].expression.type===t.Literal||a.body[0].expression.type===t.ArrayExpression||a.body[0].expression.type===t.ObjectExpression)}function ud(a,b){this.astBuilder=a;this.$filter=b}function vd(a,b){this.astBuilder=a;this.$filter=b}function Jb(a){return"constructor"==a}function ic(a){return z(a.valueOf)?a.valueOf():ng.call(a)}function uf(){var a=T(),b=T(),d={"true":!0,"false":!1,"null":null,undefined:void 0},c,e;this.addLiteral=function(a,b){d[a]=b};this.setIdentifierFns= -function(a,b){c=a;e=b;return this};this.$get=["$filter",function(f){function g(c,d,e){var g,k,C;e=e||K;switch(typeof c){case "string":C=c=c.trim();var D=e?b:a;g=D[C];if(!g){":"===c.charAt(0)&&":"===c.charAt(1)&&(k=!0,c=c.substring(2));g=e?q:I;var G=new jc(g);g=(new kc(G,f,g)).parse(c);g.constant?g.$$watchDelegate=p:k?g.$$watchDelegate=g.literal?n:m:g.inputs&&(g.$$watchDelegate=l);e&&(g=h(g));D[C]=g}return s(g,d);case "function":return s(c,d);default:return s(A,d)}}function h(a){function b(c,d,e,f){var g= -K;K=!0;try{return a(c,d,e,f)}finally{K=g}}if(!a)return a;b.$$watchDelegate=a.$$watchDelegate;b.assign=h(a.assign);b.constant=a.constant;b.literal=a.literal;for(var c=0;a.inputs&&c=this.promise.$$state.status&&d&&d.length&&a(function(){for(var a,e,f=0,g=d.length;fa)for(b in l++,f)sa.call(e,b)||(q--,delete f[b])}else f!==e&&(f=e,l++);return l}}c.$stateful=!0;var d=this,e,f,h,k=1r&&(w=4-r,x[w]||(x[w]=[]),x[w].push({msg:z(a.exp)? -"fn: "+(a.exp.name||a.exp.toString()):a.exp,newVal:g,oldVal:k}));else if(a===c){q=!1;break a}}catch(B){f(B)}if(!(p=y.$$watchersCount&&y.$$childHead||y!==this&&y.$$nextSibling))for(;y!==this&&!(p=y.$$nextSibling);)y=y.$parent}while(y=p);if((q||v.length)&&!r--)throw K.$$phase=null,d("infdig",b,x);}while(q||v.length);for(K.$$phase=null;PBa)throw ya("iequirks");var c=ga(ma);c.isEnabled=function(){return a}; -c.trustAs=d.trustAs;c.getTrusted=d.getTrusted;c.valueOf=d.valueOf;a||(c.trustAs=c.getTrusted=function(a,b){return b},c.valueOf=Ya);c.parseAs=function(a,d){var e=b(d);return e.literal&&e.constant?e:b(d,function(b){return c.getTrusted(a,b)})};var e=c.parseAs,f=c.getTrusted,g=c.trustAs;r(ma,function(a,b){var d=M(b);c[eb("parse_as_"+d)]=function(b){return e(a,b)};c[eb("get_trusted_"+d)]=function(b){return f(a,b)};c[eb("trust_as_"+d)]=function(b){return g(a,b)}});return c}]}function Af(){this.$get=["$window", -"$document",function(a,b){var d={},c=!(a.chrome&&a.chrome.app&&a.chrome.app.runtime)&&a.history&&a.history.pushState,e=aa((/android (\d+)/.exec(M((a.navigator||{}).userAgent))||[])[1]),f=/Boxee/i.test((a.navigator||{}).userAgent),g=b[0]||{},h,k=/^(Moz|webkit|ms)(?=[A-Z])/,l=g.body&&g.body.style,m=!1,n=!1;if(l){for(var p in l)if(m=k.exec(p)){h=m[0];h=h[0].toUpperCase()+h.substr(1);break}h||(h="WebkitOpacity"in l&&"webkit");m=!!("transition"in l||h+"Transition"in l);n=!!("animation"in l||h+"Animation"in -l);!e||m&&n||(m=F(l.webkitTransition),n=F(l.webkitAnimation))}return{history:!(!c||4>e||f),hasEvent:function(a){if("input"===a&&11>=Ba)return!1;if(w(d[a])){var b=g.createElement("div");d[a]="on"+a in b}return d[a]},csp:Fa(),vendorPrefix:h,transitions:m,animations:n,android:e}}]}function Cf(){var a;this.httpOptions=function(b){return b?(a=b,this):a};this.$get=["$templateCache","$http","$q","$sce",function(b,d,c,e){function f(g,h){f.totalPendingRequests++;if(!F(g)||w(b.get(g)))g=e.getTrustedResourceUrl(g); -var k=d.defaults&&d.defaults.transformResponse;J(k)?k=k.filter(function(a){return a!==dc}):k===dc&&(k=null);return d.get(g,R({cache:b,transformResponse:k},a))["finally"](function(){f.totalPendingRequests--}).then(function(a){b.put(g,a.data);return a.data},function(a){if(!h)throw pg("tpload",g,a.status,a.statusText);return c.reject(a)})}f.totalPendingRequests=0;return f}]}function Df(){this.$get=["$rootScope","$browser","$location",function(a,b,d){return{findBindings:function(a,b,d){a=a.getElementsByClassName("ng-binding"); -var g=[];r(a,function(a){var c=ea.element(a).data("$binding");c&&r(c,function(c){d?(new RegExp("(^|\\s)"+xd(b)+"(\\s|\\||$)")).test(c)&&g.push(a):-1!=c.indexOf(b)&&g.push(a)})});return g},findModels:function(a,b,d){for(var g=["ng-","data-ng-","ng\\:"],h=0;hc&&(c=e),c+=+a.slice(e+1),a=a.substring(0,e)):0>c&&(c=a.length);for(e=0;a.charAt(e)==mc;e++);if(e==(g=a.length))d=[0],c=1;else{for(g--;a.charAt(g)==mc;)g--;c-=e;d=[];for(f=0;e<=g;e++,f++)d[f]=+a.charAt(e)}c>Hd&&(d=d.splice(0,Hd-1),b=c-1,c=1);return{d:d,e:b,i:c}}function xg(a,b,d,c){var e=a.d,f=e.length-a.i;b=w(b)?Math.min(Math.max(d,f),c):+b;d=b+a.i;c=e[d];if(0d-1){for(c=0;c>d;c--)e.unshift(0),a.i++;e.unshift(1);a.i++}else e[d-1]++;for(;fh;)k.unshift(0),h++;0=b.lgSize&&h.unshift(k.splice(-b.lgSize,k.length).join(""));k.length>b.gSize;)h.unshift(k.splice(-b.gSize,k.length).join(""));k.length&&h.unshift(k.join(""));k=h.join(d);f.length&&(k+=c+f.join(""));e&&(k+="e+"+e)}return 0>a&&!g?b.negPre+k+b.negSuf:b.posPre+k+b.posSuf}function Kb(a,b,d,c){var e="";if(0>a||c&&0>=a)c?a=-a+1:(a=-a,e="-");for(a=""+a;a.length-d)f+=d;0===f&&-12==d&&(f=12);return Kb(f,b,c,e)}}function kb(a,b,d){return function(c,e){var f=c["get"+a](),g=ub((d?"STANDALONE":"")+(b?"SHORT":"")+a);return e[g][f]}}function Id(a){var b=(new Date(a,0,1)).getDay();return new Date(a,0,(4>=b?5:12)-b)}function Jd(a){return function(b){var d=Id(b.getFullYear());b=+new Date(b.getFullYear(),b.getMonth(),b.getDate()+(4-b.getDay()))-+d;b=1+Math.round(b/6048E5);return Kb(b,a)}}function nc(a, -b){return 0>=a.getFullYear()?b.ERAS[0]:b.ERAS[1]}function Cd(a){function b(a){var b;if(b=a.match(d)){a=new Date(0);var f=0,g=0,h=b[8]?a.setUTCFullYear:a.setFullYear,k=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=aa(b[9]+b[10]),g=aa(b[9]+b[11]));h.call(a,aa(b[1]),aa(b[2])-1,aa(b[3]));f=aa(b[4]||0)-f;g=aa(b[5]||0)-g;h=aa(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));k.call(a,f,g,h,b)}return a}var d=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/; -return function(c,d,f){var g="",h=[],k,l;d=d||"mediumDate";d=a.DATETIME_FORMATS[d]||d;F(c)&&(c=yg.test(c)?aa(c):b(c));S(c)&&(c=new Date(c));if(!ia(c)||!isFinite(c.getTime()))return c;for(;d;)(l=zg.exec(d))?(h=ab(h,l,1),d=h.pop()):(h.push(d),d=null);var m=c.getTimezoneOffset();f&&(m=yc(f,m),c=Sb(c,f,!0));r(h,function(b){k=Ag[b];g+=k?k(c,a.DATETIME_FORMATS,m):"''"===b?"'":b.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function rg(){return function(a,b){w(b)&&(b=2);return cb(a,b)}}function sg(){return function(a, -b,d){b=Infinity===Math.abs(Number(b))?Number(b):aa(b);if(isNaN(b))return a;S(a)&&(a=a.toString());if(!oa(a))return a;d=!d||isNaN(d)?0:aa(d);d=0>d?Math.max(0,a.length+d):d;return 0<=b?oc(a,d,d+b):0===d?oc(a,b,a.length):oc(a,Math.max(0,d+b),d)}}function oc(a,b,d){return F(a)?a.slice(b,d):ta.call(a,b,d)}function Ed(a){function b(b){return b.map(function(b){var c=1,d=Ya;if(z(b))d=b;else if(F(b)){if("+"==b.charAt(0)||"-"==b.charAt(0))c="-"==b.charAt(0)?-1:1,b=b.substring(1);if(""!==b&&(d=a(b),d.constant))var e= -d(),d=function(a){return a[e]}}return{get:d,descending:c}})}function d(a){switch(typeof a){case "number":case "boolean":case "string":return!0;default:return!1}}function c(a,b){var c=0,d=a.type,k=b.type;if(d===k){var k=a.value,l=b.value;"string"===d?(k=k.toLowerCase(),l=l.toLowerCase()):"object"===d&&(H(k)&&(k=a.index),H(l)&&(l=b.index));k!==l&&(c=kb||37<=b&&40>=b||m(a,this,this.value)});if(e.hasEvent("paste"))b.on("paste cut",m)}b.on("change",l);if(Md[g]&&c.$$hasNativeValidators&&g===d.type)b.on("keydown wheel mousedown",function(a){if(!k){var b=this.validity,c=b.badInput,d=b.typeMismatch;k=f.defer(function(){k=null;b.badInput===c&&b.typeMismatch===d||l(a)})}});c.$render=function(){var a=c.$isEmpty(c.$viewValue)? -"":c.$viewValue;b.val()!==a&&b.val(a)}}function Nb(a,b){return function(d,c){var e,f;if(ia(d))return d;if(F(d)){'"'==d.charAt(0)&&'"'==d.charAt(d.length-1)&&(d=d.substring(1,d.length-1));if(Bg.test(d))return new Date(d);a.lastIndex=0;if(e=a.exec(d))return e.shift(),f=c?{yyyy:c.getFullYear(),MM:c.getMonth()+1,dd:c.getDate(),HH:c.getHours(),mm:c.getMinutes(),ss:c.getSeconds(),sss:c.getMilliseconds()/1E3}:{yyyy:1970,MM:1,dd:1,HH:0,mm:0,ss:0,sss:0},r(e,function(a,c){c=t};g.$observe("min",function(a){t=p(a);h.$validate()})}if(x(g.max)||g.ngMax){var q;h.$validators.max=function(a){return!n(a)||w(q)||d(a)<=q};g.$observe("max",function(a){q=p(a);h.$validate()})}}}function Nd(a,b,d,c){(c.$$hasNativeValidators=H(b[0].validity))&&c.$parsers.push(function(a){var c=b.prop("validity")||{};return c.badInput||c.typeMismatch?void 0:a})}function Od(a, -b,d,c,e){if(x(c)){a=a(c);if(!a.constant)throw nb("constexpr",d,c);return a(b)}return e}function qc(a,b){a="ngClass"+a;return["$animate",function(d){function c(a,b){var c=[],d=0;a:for(;d(?:<\/\1>|)$/,Vb=/<|&#?\w+;/,Mf=/<([\w:-]+)/,Nf=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,ha={option:[1,'"],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ha.optgroup=ha.option;ha.tbody=ha.tfoot=ha.colgroup=ha.caption=ha.thead; -ha.th=ha.td;var Uf=E.Node.prototype.contains||function(a){return!!(this.compareDocumentPosition(a)&16)},Pa=U.prototype={ready:function(a){function b(){d||(d=!0,a())}var d=!1;"complete"===E.document.readyState?E.setTimeout(b):(this.on("DOMContentLoaded",b),U(E).on("load",b))},toString:function(){var a=[];r(this,function(b){a.push(""+b)});return"["+a.join(", ")+"]"},eq:function(a){return 0<=a?B(this[a]):B(this[this.length+a])},length:0,push:Dg,sort:[].sort,splice:[].splice},Eb={};r("multiple selected checked disabled readOnly required open".split(" "), -function(a){Eb[M(a)]=a});var Vc={};r("input select option textarea button form details".split(" "),function(a){Vc[a]=!0});var cd={ngMinlength:"minlength",ngMaxlength:"maxlength",ngMin:"min",ngMax:"max",ngPattern:"pattern"};r({data:Yb,removeData:fb,hasData:function(a){for(var b in gb[a.ng339])return!0;return!1},cleanData:function(a){for(var b=0,d=a.length;b/,Xf=/^[^\(]*\(\s*([^\)]*)\)/m,Eg=/,/,Fg=/^\s*(_?)(\S+?)\1\s*$/,Vf=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,Ha=O("$injector");db.$$annotate= -function(a,b,d){var c;if("function"===typeof a){if(!(c=a.$inject)){c=[];if(a.length){if(b)throw F(d)&&d||(d=a.name||Yf(a)),Ha("strictdi",d);b=Wc(a);r(b[1].split(Eg),function(a){a.replace(Fg,function(a,b,d){c.push(d)})})}a.$inject=c}}else J(a)?(b=a.length-1,Qa(a[b],"fn"),c=a.slice(0,b)):Qa(a,"fn",!0);return c};var Sd=O("$animate"),af=function(){this.$get=A},bf=function(){var a=new Sa,b=[];this.$get=["$$AnimateRunner","$rootScope",function(d,c){function e(a,b,c){var d=!1;b&&(b=F(b)?b.split(" "):J(b)? -b:[],r(b,function(b){b&&(d=!0,a[b]=c)}));return d}function f(){r(b,function(b){var c=a.get(b);if(c){var d=Zf(b.attr("class")),e="",f="";r(c,function(a,b){a!==!!d[b]&&(a?e+=(e.length?" ":"")+b:f+=(f.length?" ":"")+b)});r(b,function(a){e&&Bb(a,e);f&&Ab(a,f)});a.remove(b)}});b.length=0}return{enabled:A,on:A,off:A,pin:A,push:function(g,h,k,l){l&&l();k=k||{};k.from&&g.css(k.from);k.to&&g.css(k.to);if(k.addClass||k.removeClass)if(h=k.addClass,l=k.removeClass,k=a.get(g)||{},h=e(k,h,!0),l=e(k,l,!1),h||l)a.put(g, -k),b.push(g),1===b.length&&c.$$postDigest(f);g=new d;g.complete();return g}}}]},Ze=["$provide",function(a){var b=this;this.$$registeredAnimations=Object.create(null);this.register=function(d,c){if(d&&"."!==d.charAt(0))throw Sd("notcsel",d);var e=d+"-animation";b.$$registeredAnimations[d.substr(1)]=e;a.factory(e,c)};this.classNameFilter=function(a){if(1===arguments.length&&(this.$$classNameFilter=a instanceof RegExp?a:null)&&/(\s+|\/)ng-animate(\s+|\/)/.test(this.$$classNameFilter.toString()))throw Sd("nongcls", -"ng-animate");return this.$$classNameFilter};this.$get=["$$animateQueue",function(a){function b(a,c,d){if(d){var h;a:{for(h=0;h <= >= && || ! = |".split(" "),function(a){Ob[a]=!0});var Jg={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'},jc=function(a){this.options=a};jc.prototype={constructor:jc,lex:function(a){this.text=a;this.index=0;for(this.tokens=[];this.index=a&&"string"===typeof a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdentifierStart:function(a){return this.options.isIdentifierStart?this.options.isIdentifierStart(a,this.codePointAt(a)):this.isValidIdentifierStart(a)},isValidIdentifierStart:function(a){return"a"<=a&&"z">= -a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isIdentifierContinue:function(a){return this.options.isIdentifierContinue?this.options.isIdentifierContinue(a,this.codePointAt(a)):this.isValidIdentifierContinue(a)},isValidIdentifierContinue:function(a,b){return this.isValidIdentifierStart(a,b)||this.isNumber(a)},codePointAt:function(a){return 1===a.length?a.charCodeAt(0):(a.charCodeAt(0)<<10)+a.charCodeAt(1)-56613888},peekMultichar:function(){var a=this.text.charAt(this.index),b=this.peek();if(!b)return a;var d= -a.charCodeAt(0),c=b.charCodeAt(0);return 55296<=d&&56319>=d&&56320<=c&&57343>=c?a+b:a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,b,d){d=d||this.index;b=x(b)?"s "+b+"-"+this.index+" ["+this.text.substring(b,d)+"]":" "+d;throw ca("lexerr",a,b,this.text);},readNumber:function(){for(var a="",b=this.index;this.index","<=",">=");)a={type:t.BinaryExpression,operator:b.text,left:a,right:this.additive()};return a},additive:function(){for(var a=this.multiplicative(),b;b=this.expect("+","-");)a={type:t.BinaryExpression,operator:b.text,left:a,right:this.multiplicative()};return a},multiplicative:function(){for(var a=this.unary(),b;b=this.expect("*", -"/","%");)a={type:t.BinaryExpression,operator:b.text,left:a,right:this.unary()};return a},unary:function(){var a;return(a=this.expect("+","-","!"))?{type:t.UnaryExpression,operator:a.text,prefix:!0,argument:this.unary()}:this.primary()},primary:function(){var a;this.expect("(")?(a=this.filterChain(),this.consume(")")):this.expect("[")?a=this.arrayDeclaration():this.expect("{")?a=this.object():this.selfReferential.hasOwnProperty(this.peek().text)?a=Z(this.selfReferential[this.consume().text]):this.options.literals.hasOwnProperty(this.peek().text)? -a={type:t.Literal,value:this.options.literals[this.consume().text]}:this.peek().identifier?a=this.identifier():this.peek().constant?a=this.constant():this.throwError("not a primary expression",this.peek());for(var b;b=this.expect("(","[",".");)"("===b.text?(a={type:t.CallExpression,callee:a,arguments:this.parseArguments()},this.consume(")")):"["===b.text?(a={type:t.MemberExpression,object:a,property:this.expression(),computed:!0},this.consume("]")):"."===b.text?a={type:t.MemberExpression,object:a, -property:this.identifier(),computed:!1}:this.throwError("IMPOSSIBLE");return a},filter:function(a){a=[a];for(var b={type:t.CallExpression,callee:this.identifier(),arguments:a,filter:!0};this.expect(":");)a.push(this.expression());return b},parseArguments:function(){var a=[];if(")"!==this.peekToken().text){do a.push(this.filterChain());while(this.expect(","))}return a},identifier:function(){var a=this.consume();a.identifier||this.throwError("is not a valid identifier",a);return{type:t.Identifier,name:a.text}}, -constant:function(){return{type:t.Literal,value:this.consume().value}},arrayDeclaration:function(){var a=[];if("]"!==this.peekToken().text){do{if(this.peek("]"))break;a.push(this.expression())}while(this.expect(","))}this.consume("]");return{type:t.ArrayExpression,elements:a}},object:function(){var a=[],b;if("}"!==this.peekToken().text){do{if(this.peek("}"))break;b={type:t.Property,kind:"init"};this.peek().constant?(b.key=this.constant(),b.computed=!1,this.consume(":"),b.value=this.expression()): -this.peek().identifier?(b.key=this.identifier(),b.computed=!1,this.peek(":")?(this.consume(":"),b.value=this.expression()):b.value=b.key):this.peek("[")?(this.consume("["),b.key=this.expression(),this.consume("]"),b.computed=!0,this.consume(":"),b.value=this.expression()):this.throwError("invalid key",this.peek());a.push(b)}while(this.expect(","))}this.consume("}");return{type:t.ObjectExpression,properties:a}},throwError:function(a,b){throw ca("syntax",b.text,a,b.index+1,this.text,this.text.substring(b.index)); -},consume:function(a){if(0===this.tokens.length)throw ca("ueoe",this.text);var b=this.expect(a);b||this.throwError("is unexpected, expecting ["+a+"]",this.peek());return b},peekToken:function(){if(0===this.tokens.length)throw ca("ueoe",this.text);return this.tokens[0]},peek:function(a,b,d,c){return this.peekAhead(0,a,b,d,c)},peekAhead:function(a,b,d,c,e){if(this.tokens.length>a){a=this.tokens[a];var f=a.text;if(f===b||f===d||f===c||f===e||!(b||d||c||e))return a}return!1},expect:function(a,b,d,c){return(a= -this.peek(a,b,d,c))?(this.tokens.shift(),a):!1},selfReferential:{"this":{type:t.ThisExpression},$locals:{type:t.LocalsExpression}}};ud.prototype={compile:function(a,b){var d=this,c=this.astBuilder.ast(a);this.state={nextId:0,filters:{},expensiveChecks:b,fn:{vars:[],body:[],own:{}},assign:{vars:[],body:[],own:{}},inputs:[]};$(c,d.$filter);var e="",f;this.stage="assign";if(f=sd(c))this.state.computing="assign",e=this.nextId(),this.recurse(f,e),this.return_(e),e="fn.assign="+this.generateFunction("assign", -"s,v,l");f=qd(c.body);d.stage="inputs";r(f,function(a,b){var c="fn"+b;d.state[c]={vars:[],body:[],own:{}};d.state.computing=c;var e=d.nextId();d.recurse(a,e);d.return_(e);d.state.inputs.push(c);a.watchId=b});this.state.computing="fn";this.stage="main";this.recurse(c);e='"'+this.USE+" "+this.STRICT+'";\n'+this.filterPrefix()+"var fn="+this.generateFunction("fn","s,l,a,i")+e+this.watchFns()+"return fn;";e=(new Function("$filter","ensureSafeMemberName","ensureSafeObject","ensureSafeFunction","getStringValue", -"ensureSafeAssignContext","ifDefined","plus","text",e))(this.$filter,Ua,ra,od,ig,Ib,mg,pd,a);this.state=this.stage=void 0;e.literal=td(c);e.constant=c.constant;return e},USE:"use",STRICT:"strict",watchFns:function(){var a=[],b=this.state.inputs,d=this;r(b,function(b){a.push("var "+b+"="+d.generateFunction(b,"s"))});b.length&&a.push("fn.inputs=["+b.join(",")+"];");return a.join("")},generateFunction:function(a,b){return"function("+b+"){"+this.varsPrefix(a)+this.body(a)+"};"},filterPrefix:function(){var a= -[],b=this;r(this.state.filters,function(d,c){a.push(d+"=$filter("+b.escape(c)+")")});return a.length?"var "+a.join(",")+";":""},varsPrefix:function(a){return this.state[a].vars.length?"var "+this.state[a].vars.join(",")+";":""},body:function(a){return this.state[a].body.join("")},recurse:function(a,b,d,c,e,f){var g,h,k=this,l,m,n;c=c||A;if(!f&&x(a.watchId))b=b||this.nextId(),this.if_("i",this.lazyAssign(b,this.computedMember("i",a.watchId)),this.lazyRecurse(a,b,d,c,e,!0));else switch(a.type){case t.Program:r(a.body, -function(b,c){k.recurse(b.expression,void 0,void 0,function(a){h=a});c!==a.body.length-1?k.current().body.push(h,";"):k.return_(h)});break;case t.Literal:m=this.escape(a.value);this.assign(b,m);c(m);break;case t.UnaryExpression:this.recurse(a.argument,void 0,void 0,function(a){h=a});m=a.operator+"("+this.ifDefined(h,0)+")";this.assign(b,m);c(m);break;case t.BinaryExpression:this.recurse(a.left,void 0,void 0,function(a){g=a});this.recurse(a.right,void 0,void 0,function(a){h=a});m="+"===a.operator? -this.plus(g,h):"-"===a.operator?this.ifDefined(g,0)+a.operator+this.ifDefined(h,0):"("+g+")"+a.operator+"("+h+")";this.assign(b,m);c(m);break;case t.LogicalExpression:b=b||this.nextId();k.recurse(a.left,b);k.if_("&&"===a.operator?b:k.not(b),k.lazyRecurse(a.right,b));c(b);break;case t.ConditionalExpression:b=b||this.nextId();k.recurse(a.test,b);k.if_(b,k.lazyRecurse(a.alternate,b),k.lazyRecurse(a.consequent,b));c(b);break;case t.Identifier:b=b||this.nextId();d&&(d.context="inputs"===k.stage?"s":this.assign(this.nextId(), -this.getHasOwnProperty("l",a.name)+"?l:s"),d.computed=!1,d.name=a.name);Ua(a.name);k.if_("inputs"===k.stage||k.not(k.getHasOwnProperty("l",a.name)),function(){k.if_("inputs"===k.stage||"s",function(){e&&1!==e&&k.if_(k.not(k.nonComputedMember("s",a.name)),k.lazyAssign(k.nonComputedMember("s",a.name),"{}"));k.assign(b,k.nonComputedMember("s",a.name))})},b&&k.lazyAssign(b,k.nonComputedMember("l",a.name)));(k.state.expensiveChecks||Jb(a.name))&&k.addEnsureSafeObject(b);c(b);break;case t.MemberExpression:g= -d&&(d.context=this.nextId())||this.nextId();b=b||this.nextId();k.recurse(a.object,g,void 0,function(){k.if_(k.notNull(g),function(){e&&1!==e&&k.addEnsureSafeAssignContext(g);if(a.computed)h=k.nextId(),k.recurse(a.property,h),k.getStringValue(h),k.addEnsureSafeMemberName(h),e&&1!==e&&k.if_(k.not(k.computedMember(g,h)),k.lazyAssign(k.computedMember(g,h),"{}")),m=k.ensureSafeObject(k.computedMember(g,h)),k.assign(b,m),d&&(d.computed=!0,d.name=h);else{Ua(a.property.name);e&&1!==e&&k.if_(k.not(k.nonComputedMember(g, -a.property.name)),k.lazyAssign(k.nonComputedMember(g,a.property.name),"{}"));m=k.nonComputedMember(g,a.property.name);if(k.state.expensiveChecks||Jb(a.property.name))m=k.ensureSafeObject(m);k.assign(b,m);d&&(d.computed=!1,d.name=a.property.name)}},function(){k.assign(b,"undefined")});c(b)},!!e);break;case t.CallExpression:b=b||this.nextId();a.filter?(h=k.filter(a.callee.name),l=[],r(a.arguments,function(a){var b=k.nextId();k.recurse(a,b);l.push(b)}),m=h+"("+l.join(",")+")",k.assign(b,m),c(b)):(h= -k.nextId(),g={},l=[],k.recurse(a.callee,h,g,function(){k.if_(k.notNull(h),function(){k.addEnsureSafeFunction(h);r(a.arguments,function(a){k.recurse(a,k.nextId(),void 0,function(a){l.push(k.ensureSafeObject(a))})});g.name?(k.state.expensiveChecks||k.addEnsureSafeObject(g.context),m=k.member(g.context,g.name,g.computed)+"("+l.join(",")+")"):m=h+"("+l.join(",")+")";m=k.ensureSafeObject(m);k.assign(b,m)},function(){k.assign(b,"undefined")});c(b)}));break;case t.AssignmentExpression:h=this.nextId();g= -{};if(!rd(a.left))throw ca("lval");this.recurse(a.left,void 0,g,function(){k.if_(k.notNull(g.context),function(){k.recurse(a.right,h);k.addEnsureSafeObject(k.member(g.context,g.name,g.computed));k.addEnsureSafeAssignContext(g.context);m=k.member(g.context,g.name,g.computed)+a.operator+h;k.assign(b,m);c(b||m)})},1);break;case t.ArrayExpression:l=[];r(a.elements,function(a){k.recurse(a,k.nextId(),void 0,function(a){l.push(a)})});m="["+l.join(",")+"]";this.assign(b,m);c(m);break;case t.ObjectExpression:l= -[];n=!1;r(a.properties,function(a){a.computed&&(n=!0)});n?(b=b||this.nextId(),this.assign(b,"{}"),r(a.properties,function(a){a.computed?(g=k.nextId(),k.recurse(a.key,g)):g=a.key.type===t.Identifier?a.key.name:""+a.key.value;h=k.nextId();k.recurse(a.value,h);k.assign(k.member(b,g,a.computed),h)})):(r(a.properties,function(b){k.recurse(b.value,a.constant?void 0:k.nextId(),void 0,function(a){l.push(k.escape(b.key.type===t.Identifier?b.key.name:""+b.key.value)+":"+a)})}),m="{"+l.join(",")+"}",this.assign(b, -m));c(b||m);break;case t.ThisExpression:this.assign(b,"s");c("s");break;case t.LocalsExpression:this.assign(b,"l");c("l");break;case t.NGValueParameter:this.assign(b,"v"),c("v")}},getHasOwnProperty:function(a,b){var d=a+"."+b,c=this.current().own;c.hasOwnProperty(d)||(c[d]=this.nextId(!1,a+"&&("+this.escape(b)+" in "+a+")"));return c[d]},assign:function(a,b){if(a)return this.current().body.push(a,"=",b,";"),a},filter:function(a){this.state.filters.hasOwnProperty(a)||(this.state.filters[a]=this.nextId(!0)); -return this.state.filters[a]},ifDefined:function(a,b){return"ifDefined("+a+","+this.escape(b)+")"},plus:function(a,b){return"plus("+a+","+b+")"},return_:function(a){this.current().body.push("return ",a,";")},if_:function(a,b,d){if(!0===a)b();else{var c=this.current().body;c.push("if(",a,"){");b();c.push("}");d&&(c.push("else{"),d(),c.push("}"))}},not:function(a){return"!("+a+")"},notNull:function(a){return a+"!=null"},nonComputedMember:function(a,b){var d=/[^$_a-zA-Z0-9]/g;return/[$_a-zA-Z][$_a-zA-Z0-9]*/.test(b)? -a+"."+b:a+'["'+b.replace(d,this.stringEscapeFn)+'"]'},computedMember:function(a,b){return a+"["+b+"]"},member:function(a,b,d){return d?this.computedMember(a,b):this.nonComputedMember(a,b)},addEnsureSafeObject:function(a){this.current().body.push(this.ensureSafeObject(a),";")},addEnsureSafeMemberName:function(a){this.current().body.push(this.ensureSafeMemberName(a),";")},addEnsureSafeFunction:function(a){this.current().body.push(this.ensureSafeFunction(a),";")},addEnsureSafeAssignContext:function(a){this.current().body.push(this.ensureSafeAssignContext(a), -";")},ensureSafeObject:function(a){return"ensureSafeObject("+a+",text)"},ensureSafeMemberName:function(a){return"ensureSafeMemberName("+a+",text)"},ensureSafeFunction:function(a){return"ensureSafeFunction("+a+",text)"},getStringValue:function(a){this.assign(a,"getStringValue("+a+")")},ensureSafeAssignContext:function(a){return"ensureSafeAssignContext("+a+",text)"},lazyRecurse:function(a,b,d,c,e,f){var g=this;return function(){g.recurse(a,b,d,c,e,f)}},lazyAssign:function(a,b){var d=this;return function(){d.assign(a, -b)}},stringEscapeRegex:/[^ a-zA-Z0-9]/g,stringEscapeFn:function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)},escape:function(a){if(F(a))return"'"+a.replace(this.stringEscapeRegex,this.stringEscapeFn)+"'";if(S(a))return a.toString();if(!0===a)return"true";if(!1===a)return"false";if(null===a)return"null";if("undefined"===typeof a)return"undefined";throw ca("esc");},nextId:function(a,b){var d="v"+this.state.nextId++;a||this.current().vars.push(d+(b?"="+b:""));return d},current:function(){return this.state[this.state.computing]}}; -vd.prototype={compile:function(a,b){var d=this,c=this.astBuilder.ast(a);this.expression=a;this.expensiveChecks=b;$(c,d.$filter);var e,f;if(e=sd(c))f=this.recurse(e);e=qd(c.body);var g;e&&(g=[],r(e,function(a,b){var c=d.recurse(a);a.input=c;g.push(c);a.watchId=b}));var h=[];r(c.body,function(a){h.push(d.recurse(a.expression))});e=0===c.body.length?A:1===c.body.length?h[0]:function(a,b){var c;r(h,function(d){c=d(a,b)});return c};f&&(e.assign=function(a,b,c){return f(a,c,b)});g&&(e.inputs=g);e.literal= -td(c);e.constant=c.constant;return e},recurse:function(a,b,d){var c,e,f=this,g;if(a.input)return this.inputs(a.input,a.watchId);switch(a.type){case t.Literal:return this.value(a.value,b);case t.UnaryExpression:return e=this.recurse(a.argument),this["unary"+a.operator](e,b);case t.BinaryExpression:return c=this.recurse(a.left),e=this.recurse(a.right),this["binary"+a.operator](c,e,b);case t.LogicalExpression:return c=this.recurse(a.left),e=this.recurse(a.right),this["binary"+a.operator](c,e,b);case t.ConditionalExpression:return this["ternary?:"](this.recurse(a.test), -this.recurse(a.alternate),this.recurse(a.consequent),b);case t.Identifier:return Ua(a.name,f.expression),f.identifier(a.name,f.expensiveChecks||Jb(a.name),b,d,f.expression);case t.MemberExpression:return c=this.recurse(a.object,!1,!!d),a.computed||(Ua(a.property.name,f.expression),e=a.property.name),a.computed&&(e=this.recurse(a.property)),a.computed?this.computedMember(c,e,b,d,f.expression):this.nonComputedMember(c,e,f.expensiveChecks,b,d,f.expression);case t.CallExpression:return g=[],r(a.arguments, -function(a){g.push(f.recurse(a))}),a.filter&&(e=this.$filter(a.callee.name)),a.filter||(e=this.recurse(a.callee,!0)),a.filter?function(a,c,d,f){for(var n=[],p=0;p":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)>b(c,e,f,g);return d?{value:c}:c}},"binary<=":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)<=b(c,e,f,g);return d?{value:c}:c}},"binary>=":function(a, -b,d){return function(c,e,f,g){c=a(c,e,f,g)>=b(c,e,f,g);return d?{value:c}:c}},"binary&&":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)&&b(c,e,f,g);return d?{value:c}:c}},"binary||":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)||b(c,e,f,g);return d?{value:c}:c}},"ternary?:":function(a,b,d,c){return function(e,f,g,h){e=a(e,f,g,h)?b(e,f,g,h):d(e,f,g,h);return c?{value:e}:e}},value:function(a,b){return function(){return b?{context:void 0,name:void 0,value:a}:a}},identifier:function(a, -b,d,c,e){return function(f,g,h,k){f=g&&a in g?g:f;c&&1!==c&&f&&!f[a]&&(f[a]={});g=f?f[a]:void 0;b&&ra(g,e);return d?{context:f,name:a,value:g}:g}},computedMember:function(a,b,d,c,e){return function(f,g,h,k){var l=a(f,g,h,k),m,n;null!=l&&(m=b(f,g,h,k),m+="",Ua(m,e),c&&1!==c&&(Ib(l),l&&!l[m]&&(l[m]={})),n=l[m],ra(n,e));return d?{context:l,name:m,value:n}:n}},nonComputedMember:function(a,b,d,c,e,f){return function(g,h,k,l){g=a(g,h,k,l);e&&1!==e&&(Ib(g),g&&!g[b]&&(g[b]={}));h=null!=g?g[b]:void 0;(d|| -Jb(b))&&ra(h,f);return c?{context:g,name:b,value:h}:h}},inputs:function(a,b){return function(d,c,e,f){return f?f[b]:a(d,c,e)}}};var kc=function(a,b,d){this.lexer=a;this.$filter=b;this.options=d;this.ast=new t(a,d);this.astCompiler=d.csp?new vd(this.ast,b):new ud(this.ast,b)};kc.prototype={constructor:kc,parse:function(a){return this.astCompiler.compile(a,this.options.expensiveChecks)}};var ng=Object.prototype.valueOf,ya=O("$sce"),ma={HTML:"html",CSS:"css",URL:"url",RESOURCE_URL:"resourceUrl",JS:"js"}, -pg=O("$compile"),Y=E.document.createElement("a"),zd=qa(E.location.href);Ad.$inject=["$document"];Mc.$inject=["$provide"];var Hd=22,Gd=".",mc="0";Bd.$inject=["$locale"];Dd.$inject=["$locale"];var Ag={yyyy:X("FullYear",4,0,!1,!0),yy:X("FullYear",2,0,!0,!0),y:X("FullYear",1,0,!1,!0),MMMM:kb("Month"),MMM:kb("Month",!0),MM:X("Month",2,1),M:X("Month",1,1),LLLL:kb("Month",!1,!0),dd:X("Date",2),d:X("Date",1),HH:X("Hours",2),H:X("Hours",1),hh:X("Hours",2,-12),h:X("Hours",1,-12),mm:X("Minutes",2),m:X("Minutes", -1),ss:X("Seconds",2),s:X("Seconds",1),sss:X("Milliseconds",3),EEEE:kb("Day"),EEE:kb("Day",!0),a:function(a,b){return 12>a.getHours()?b.AMPMS[0]:b.AMPMS[1]},Z:function(a,b,d){a=-1*d;return a=(0<=a?"+":"")+(Kb(Math[0=a.getFullYear()?b.ERANAMES[0]:b.ERANAMES[1]}},zg=/((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,yg=/^\-?\d+$/;Cd.$inject=["$locale"]; -var tg=da(M),ug=da(ub);Ed.$inject=["$parse"];var pe=da({restrict:"E",compile:function(a,b){if(!b.href&&!b.xlinkHref)return function(a,b){if("a"===b[0].nodeName.toLowerCase()){var e="[object SVGAnimatedString]"===ka.call(b.prop("href"))?"xlink:href":"href";b.on("click",function(a){b.attr(e)||a.preventDefault()})}}}}),vb={};r(Eb,function(a,b){function d(a,d,e){a.$watch(e[c],function(a){e.$set(b,!!a)})}if("multiple"!=a){var c=xa("ng-"+b),e=d;"checked"===a&&(e=function(a,b,e){e.ngModel!==e[c]&&d(a,b, -e)});vb[c]=function(){return{restrict:"A",priority:100,link:e}}}});r(cd,function(a,b){vb[b]=function(){return{priority:100,link:function(a,c,e){if("ngPattern"===b&&"/"==e.ngPattern.charAt(0)&&(c=e.ngPattern.match(Cg))){e.$set("ngPattern",new RegExp(c[1],c[2]));return}a.$watch(e[b],function(a){e.$set(b,a)})}}}});r(["src","srcset","href"],function(a){var b=xa("ng-"+a);vb[b]=function(){return{priority:99,link:function(d,c,e){var f=a,g=a;"href"===a&&"[object SVGAnimatedString]"===ka.call(c.prop("href"))&& -(g="xlinkHref",e.$attr[g]="xlink:href",f=null);e.$observe(b,function(b){b?(e.$set(g,b),Ba&&f&&c.prop(f,e[g])):"href"===a&&e.$set(g,null)})}}}});var Lb={$addControl:A,$$renameControl:function(a,b){a.$name=b},$removeControl:A,$setValidity:A,$setDirty:A,$setPristine:A,$setSubmitted:A};Kd.$inject=["$element","$attrs","$scope","$animate","$interpolate"];var Td=function(a){return["$timeout","$parse",function(b,d){function c(a){return""===a?d('this[""]').assign:d(a).assign||A}return{name:"form",restrict:a? -"EAC":"E",require:["form","^^?form"],controller:Kd,compile:function(d,f){d.addClass(Va).addClass(ob);var g=f.name?"name":a&&f.ngForm?"ngForm":!1;return{pre:function(a,d,e,f){var n=f[0];if(!("action"in e)){var p=function(b){a.$apply(function(){n.$commitViewValue();n.$setSubmitted()});b.preventDefault()};d[0].addEventListener("submit",p,!1);d.on("$destroy",function(){b(function(){d[0].removeEventListener("submit",p,!1)},0,!1)})}(f[1]||n.$$parentForm).$addControl(n);var s=g?c(n.$name):A;g&&(s(a,n),e.$observe(g, -function(b){n.$name!==b&&(s(a,void 0),n.$$parentForm.$$renameControl(n,b),s=c(n.$name),s(a,n))}));d.on("$destroy",function(){n.$$parentForm.$removeControl(n);s(a,void 0);R(n,Lb)})}}}}}]},qe=Td(),De=Td(!0),Bg=/^\d{4,}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+(?:[+-][0-2]\d:[0-5]\d|Z)$/,Kg=/^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+\])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i,Lg=/^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+\/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+\/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/, -Mg=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/,Ud=/^(\d{4,})-(\d{2})-(\d{2})$/,Vd=/^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,rc=/^(\d{4,})-W(\d\d)$/,Wd=/^(\d{4,})-(\d\d)$/,Xd=/^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,Md=T();r(["date","datetime-local","month","time","week"],function(a){Md[a]=!0});var Yd={text:function(a,b,d,c,e,f){lb(a,b,d,c,e,f);pc(c)},date:mb("date",Ud,Nb(Ud,["yyyy","MM","dd"]),"yyyy-MM-dd"),"datetime-local":mb("datetimelocal",Vd,Nb(Vd,"yyyy MM dd HH mm ss sss".split(" ")), -"yyyy-MM-ddTHH:mm:ss.sss"),time:mb("time",Xd,Nb(Xd,["HH","mm","ss","sss"]),"HH:mm:ss.sss"),week:mb("week",rc,function(a,b){if(ia(a))return a;if(F(a)){rc.lastIndex=0;var d=rc.exec(a);if(d){var c=+d[1],e=+d[2],f=d=0,g=0,h=0,k=Id(c),e=7*(e-1);b&&(d=b.getHours(),f=b.getMinutes(),g=b.getSeconds(),h=b.getMilliseconds());return new Date(c,0,k.getDate()+e,d,f,g,h)}}return NaN},"yyyy-Www"),month:mb("month",Wd,Nb(Wd,["yyyy","MM"]),"yyyy-MM"),number:function(a,b,d,c,e,f){Nd(a,b,d,c);lb(a,b,d,c,e,f);c.$$parserName= -"number";c.$parsers.push(function(a){if(c.$isEmpty(a))return null;if(Mg.test(a))return parseFloat(a)});c.$formatters.push(function(a){if(!c.$isEmpty(a)){if(!S(a))throw nb("numfmt",a);a=a.toString()}return a});if(x(d.min)||d.ngMin){var g;c.$validators.min=function(a){return c.$isEmpty(a)||w(g)||a>=g};d.$observe("min",function(a){x(a)&&!S(a)&&(a=parseFloat(a,10));g=S(a)&&!isNaN(a)?a:void 0;c.$validate()})}if(x(d.max)||d.ngMax){var h;c.$validators.max=function(a){return c.$isEmpty(a)||w(h)||a<=h};d.$observe("max", -function(a){x(a)&&!S(a)&&(a=parseFloat(a,10));h=S(a)&&!isNaN(a)?a:void 0;c.$validate()})}},url:function(a,b,d,c,e,f){lb(a,b,d,c,e,f);pc(c);c.$$parserName="url";c.$validators.url=function(a,b){var d=a||b;return c.$isEmpty(d)||Kg.test(d)}},email:function(a,b,d,c,e,f){lb(a,b,d,c,e,f);pc(c);c.$$parserName="email";c.$validators.email=function(a,b){var d=a||b;return c.$isEmpty(d)||Lg.test(d)}},radio:function(a,b,d,c){w(d.name)&&b.attr("name",++pb);b.on("click",function(a){b[0].checked&&c.$setViewValue(d.value, -a&&a.type)});c.$render=function(){b[0].checked=d.value==c.$viewValue};d.$observe("value",c.$render)},checkbox:function(a,b,d,c,e,f,g,h){var k=Od(h,a,"ngTrueValue",d.ngTrueValue,!0),l=Od(h,a,"ngFalseValue",d.ngFalseValue,!1);b.on("click",function(a){c.$setViewValue(b[0].checked,a&&a.type)});c.$render=function(){b[0].checked=c.$viewValue};c.$isEmpty=function(a){return!1===a};c.$formatters.push(function(a){return na(a,k)});c.$parsers.push(function(a){return a?k:l})},hidden:A,button:A,submit:A,reset:A, -file:A},Gc=["$browser","$sniffer","$filter","$parse",function(a,b,d,c){return{restrict:"E",require:["?ngModel"],link:{pre:function(e,f,g,h){h[0]&&(Yd[M(g.type)]||Yd.text)(e,f,g,h[0],b,a,d,c)}}}}],Ng=/^(true|false|\d+)$/,Ve=function(){return{restrict:"A",priority:100,compile:function(a,b){return Ng.test(b.ngValue)?function(a,b,e){e.$set("value",a.$eval(e.ngValue))}:function(a,b,e){a.$watch(e.ngValue,function(a){e.$set("value",a)})}}}},ve=["$compile",function(a){return{restrict:"AC",compile:function(b){a.$$addBindingClass(b); -return function(b,c,e){a.$$addBindingInfo(c,e.ngBind);c=c[0];b.$watch(e.ngBind,function(a){c.textContent=w(a)?"":a})}}}}],xe=["$interpolate","$compile",function(a,b){return{compile:function(d){b.$$addBindingClass(d);return function(c,d,f){c=a(d.attr(f.$attr.ngBindTemplate));b.$$addBindingInfo(d,c.expressions);d=d[0];f.$observe("ngBindTemplate",function(a){d.textContent=w(a)?"":a})}}}}],we=["$sce","$parse","$compile",function(a,b,d){return{restrict:"A",compile:function(c,e){var f=b(e.ngBindHtml),g= -b(e.ngBindHtml,function(b){return a.valueOf(b)});d.$$addBindingClass(c);return function(b,c,e){d.$$addBindingInfo(c,e.ngBindHtml);b.$watch(g,function(){var d=f(b);c.html(a.getTrustedHtml(d)||"")})}}}}],Ue=da({restrict:"A",require:"ngModel",link:function(a,b,d,c){c.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),ye=qc("",!0),Ae=qc("Odd",0),ze=qc("Even",1),Be=Ma({compile:function(a,b){b.$set("ngCloak",void 0);a.removeClass("ng-cloak")}}),Ce=[function(){return{restrict:"A",scope:!0,controller:"@", -priority:500}}],Lc={},Og={blur:!0,focus:!0};r("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var b=xa("ng-"+a);Lc[b]=["$parse","$rootScope",function(d,c){return{restrict:"A",compile:function(e,f){var g=d(f[b],null,!0);return function(b,d){d.on(a,function(d){var e=function(){g(b,{$event:d})};Og[a]&&c.$$phase?b.$evalAsync(e):b.$apply(e)})}}}}]});var Fe=["$animate","$compile",function(a, -b){return{multiElement:!0,transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(d,c,e,f,g){var h,k,l;d.$watch(e.ngIf,function(d){d?k||g(function(d,f){k=f;d[d.length++]=b.$$createComment("end ngIf",e.ngIf);h={clone:d};a.enter(d,c.parent(),c)}):(l&&(l.remove(),l=null),k&&(k.$destroy(),k=null),h&&(l=tb(h.clone),a.leave(l).then(function(){l=null}),h=null))})}}}],Ge=["$templateRequest","$anchorScroll","$animate",function(a,b,d){return{restrict:"ECA",priority:400,terminal:!0, -transclude:"element",controller:ea.noop,compile:function(c,e){var f=e.ngInclude||e.src,g=e.onload||"",h=e.autoscroll;return function(c,e,m,n,p){var s=0,r,t,q,w=function(){t&&(t.remove(),t=null);r&&(r.$destroy(),r=null);q&&(d.leave(q).then(function(){t=null}),t=q,q=null)};c.$watch(f,function(f){var m=function(){!x(h)||h&&!c.$eval(h)||b()},t=++s;f?(a(f,!0).then(function(a){if(!c.$$destroyed&&t===s){var b=c.$new();n.template=a;a=p(b,function(a){w();d.enter(a,null,e).then(m)});r=b;q=a;r.$emit("$includeContentLoaded", -f);c.$eval(g)}},function(){c.$$destroyed||t!==s||(w(),c.$emit("$includeContentError",f))}),c.$emit("$includeContentRequested",f)):(w(),n.template=null)})}}}}],Xe=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(b,d,c,e){ka.call(d[0]).match(/SVG/)?(d.empty(),a(Oc(e.template,E.document).childNodes)(b,function(a){d.append(a)},{futureParentElement:d})):(d.html(e.template),a(d.contents())(b))}}}],He=Ma({priority:450,compile:function(){return{pre:function(a, -b,d){a.$eval(d.ngInit)}}}}),Te=function(){return{restrict:"A",priority:100,require:"ngModel",link:function(a,b,d,c){var e=b.attr(d.$attr.ngList)||", ",f="false"!==d.ngTrim,g=f?W(e):e;c.$parsers.push(function(a){if(!w(a)){var b=[];a&&r(a.split(g),function(a){a&&b.push(f?W(a):a)});return b}});c.$formatters.push(function(a){if(J(a))return a.join(e)});c.$isEmpty=function(a){return!a||!a.length}}}},ob="ng-valid",Pd="ng-invalid",Va="ng-pristine",Mb="ng-dirty",Rd="ng-pending",nb=O("ngModel"),Pg=["$scope", -"$exceptionHandler","$attrs","$element","$parse","$animate","$timeout","$rootScope","$q","$interpolate",function(a,b,d,c,e,f,g,h,k,l){this.$modelValue=this.$viewValue=Number.NaN;this.$$rawModelValue=void 0;this.$validators={};this.$asyncValidators={};this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$untouched=!0;this.$touched=!1;this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$error={};this.$$success={};this.$pending=void 0;this.$name=l(d.name||"",!1)(a); -this.$$parentForm=Lb;var m=e(d.ngModel),n=m.assign,p=m,s=n,t=null,I,q=this;this.$$setOptions=function(a){if((q.$options=a)&&a.getterSetter){var b=e(d.ngModel+"()"),f=e(d.ngModel+"($$$p)");p=function(a){var c=m(a);z(c)&&(c=b(a));return c};s=function(a,b){z(m(a))?f(a,{$$$p:b}):n(a,b)}}else if(!m.assign)throw nb("nonassign",d.ngModel,va(c));};this.$render=A;this.$isEmpty=function(a){return w(a)||""===a||null===a||a!==a};this.$$updateEmptyClasses=function(a){q.$isEmpty(a)?(f.removeClass(c,"ng-not-empty"), -f.addClass(c,"ng-empty")):(f.removeClass(c,"ng-empty"),f.addClass(c,"ng-not-empty"))};var K=0;Ld({ctrl:this,$element:c,set:function(a,b){a[b]=!0},unset:function(a,b){delete a[b]},$animate:f});this.$setPristine=function(){q.$dirty=!1;q.$pristine=!0;f.removeClass(c,Mb);f.addClass(c,Va)};this.$setDirty=function(){q.$dirty=!0;q.$pristine=!1;f.removeClass(c,Va);f.addClass(c,Mb);q.$$parentForm.$setDirty()};this.$setUntouched=function(){q.$touched=!1;q.$untouched=!0;f.setClass(c,"ng-untouched","ng-touched")}; -this.$setTouched=function(){q.$touched=!0;q.$untouched=!1;f.setClass(c,"ng-touched","ng-untouched")};this.$rollbackViewValue=function(){g.cancel(t);q.$viewValue=q.$$lastCommittedViewValue;q.$render()};this.$validate=function(){if(!S(q.$modelValue)||!isNaN(q.$modelValue)){var a=q.$$rawModelValue,b=q.$valid,c=q.$modelValue,d=q.$options&&q.$options.allowInvalid;q.$$runValidators(a,q.$$lastCommittedViewValue,function(e){d||b===e||(q.$modelValue=e?a:void 0,q.$modelValue!==c&&q.$$writeModelToScope())})}}; -this.$$runValidators=function(a,b,c){function d(){var c=!0;r(q.$validators,function(d,e){var g=d(a,b);c=c&&g;f(e,g)});return c?!0:(r(q.$asyncValidators,function(a,b){f(b,null)}),!1)}function e(){var c=[],d=!0;r(q.$asyncValidators,function(e,g){var h=e(a,b);if(!h||!z(h.then))throw nb("nopromise",h);f(g,void 0);c.push(h.then(function(){f(g,!0)},function(){d=!1;f(g,!1)}))});c.length?k.all(c).then(function(){g(d)},A):g(!0)}function f(a,b){h===K&&q.$setValidity(a,b)}function g(a){h===K&&c(a)}K++;var h= -K;(function(){var a=q.$$parserName||"parse";if(w(I))f(a,null);else return I||(r(q.$validators,function(a,b){f(b,null)}),r(q.$asyncValidators,function(a,b){f(b,null)})),f(a,I),I;return!0})()?d()?e():g(!1):g(!1)};this.$commitViewValue=function(){var a=q.$viewValue;g.cancel(t);if(q.$$lastCommittedViewValue!==a||""===a&&q.$$hasNativeValidators)q.$$updateEmptyClasses(a),q.$$lastCommittedViewValue=a,q.$pristine&&this.$setDirty(),this.$$parseAndValidate()};this.$$parseAndValidate=function(){var b=q.$$lastCommittedViewValue; -if(I=w(b)?void 0:!0)for(var c=0;ce||c.$isEmpty(b)||b.length<=e}}}}},Jc=function(){return{restrict:"A",require:"?ngModel",link:function(a,b,d,c){if(c){var e=0;d.$observe("minlength",function(a){e=aa(a)||0;c.$validate()});c.$validators.minlength=function(a,b){return c.$isEmpty(b)||b.length>=e}}}}};E.angular.bootstrap?E.console&&console.log("WARNING: Tried to load angular more than once."):(ke(),me(ea),ea.module("ngLocale",[],["$provide",function(a){function b(a){a+= -"";var b=a.indexOf(".");return-1==b?0:a.length-b-1}a.value("$locale",{DATETIME_FORMATS:{AMPMS:["AM","PM"],DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),ERANAMES:["Before Christ","Anno Domini"],ERAS:["BC","AD"],FIRSTDAYOFWEEK:6,MONTH:"January February March April May June July August September October November December".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),STANDALONEMONTH:"January February March April May June July August September October November December".split(" "), -WEEKENDRANGE:[5,6],fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",medium:"MMM d, y h:mm:ss a",mediumDate:"MMM d, y",mediumTime:"h:mm:ss a","short":"M/d/yy h:mm a",shortDate:"M/d/yy",shortTime:"h:mm a"},NUMBER_FORMATS:{CURRENCY_SYM:"$",DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{gSize:3,lgSize:3,maxFrac:3,minFrac:0,minInt:1,negPre:"-",negSuf:"",posPre:"",posSuf:""},{gSize:3,lgSize:3,maxFrac:2,minFrac:2,minInt:1,negPre:"-\u00a4",negSuf:"",posPre:"\u00a4",posSuf:""}]},id:"en-us",localeID:"en_US",pluralCat:function(a, -c){var e=a|0,f=c;void 0===f&&(f=Math.min(b(a),3));Math.pow(10,f);return 1==e&&0==f?"one":"other"}})}]),B(E.document).ready(function(){ge(E.document,Bc)}))})(window);!window.angular.$$csp().noInlineStyle&&window.angular.element(document.head).prepend(''); -//# sourceMappingURL=angular.min.js.map diff --git a/spring-rest-angular/src/main/webapp/resources/vendor/angular/angular.min.js.map b/spring-rest-angular/src/main/webapp/resources/vendor/angular/angular.min.js.map deleted file mode 100644 index 6d34cd22b3..0000000000 --- a/spring-rest-angular/src/main/webapp/resources/vendor/angular/angular.min.js.map +++ /dev/null @@ -1,8 +0,0 @@ -{ -"version":3, -"file":"angular.min.js", -"lineCount":315, -"mappings":"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", -"sources":["angular.js"], -"names":["window","minErr","isArrayLike","obj","isWindow","isArray","isString","jqLite","length","Object","isNumber","Array","item","forEach","iterator","context","key","isFunction","hasOwnProperty","call","isPrimitive","isBlankObject","forEachSorted","keys","sort","i","reverseParams","iteratorFn","value","nextUid","uid","baseExtend","dst","objs","deep","h","$$hashKey","ii","isObject","j","jj","src","isDate","Date","valueOf","isRegExp","RegExp","nodeName","cloneNode","isElement","clone","extend","slice","arguments","merge","toInt","str","parseInt","inherit","parent","extra","create","noop","identity","$","valueFn","valueRef","hasCustomToString","toString","isUndefined","isDefined","getPrototypeOf","isScope","$evalAsync","$watch","isBoolean","isTypedArray","TYPED_ARRAY_REGEXP","test","node","prop","attr","find","makeMap","items","split","nodeName_","element","lowercase","arrayRemove","array","index","indexOf","splice","copy","source","destination","copyRecurse","push","copyElement","stackSource","stackDest","ngMinErr","needsRecurse","copyType","undefined","constructor","buffer","copied","ArrayBuffer","byteLength","set","Uint8Array","re","match","lastIndex","type","equals","o1","o2","t1","t2","getTime","keySet","createMap","charAt","concat","array1","array2","bind","self","fn","curryArgs","startIndex","apply","toJsonReplacer","val","document","toJson","pretty","JSON","stringify","fromJson","json","parse","timezoneToOffset","timezone","fallback","replace","ALL_COLONS","requestedTimezoneOffset","isNaN","convertTimezoneToLocal","date","reverse","dateTimezoneOffset","getTimezoneOffset","timezoneOffset","setMinutes","getMinutes","minutes","startingTag","empty","e","elemHtml","append","html","nodeType","NODE_TYPE_TEXT","tryDecodeURIComponent","decodeURIComponent","parseKeyValue","keyValue","splitPoint","substring","toKeyValue","parts","arrayValue","encodeUriQuery","join","encodeUriSegment","pctEncodeSpaces","encodeURIComponent","getNgAttribute","ngAttr","ngAttrPrefixes","getAttribute","angularInit","bootstrap","appElement","module","config","prefix","name","hasAttribute","candidate","querySelector","strictDi","modules","defaultConfig","doBootstrap","injector","tag","unshift","$provide","debugInfoEnabled","$compileProvider","createInjector","invoke","bootstrapApply","scope","compile","$apply","data","NG_ENABLE_DEBUG_INFO","NG_DEFER_BOOTSTRAP","angular","resumeBootstrap","angular.resumeBootstrap","extraModules","resumeDeferredBootstrap","reloadWithDebugInfo","location","reload","getTestability","rootElement","get","snake_case","separator","SNAKE_CASE_REGEXP","letter","pos","toLowerCase","bindJQuery","originalCleanData","bindJQueryFired","jqName","jq","jQuery","on","JQLitePrototype","isolateScope","controller","inheritedData","cleanData","jQuery.cleanData","elems","events","elem","_data","$destroy","triggerHandler","JQLite","assertArg","arg","reason","assertArgFn","acceptArrayAnnotation","assertNotHasOwnProperty","getter","path","bindFnToScope","lastInstance","len","getBlockNodes","nodes","endNode","blockNodes","nextSibling","setupModuleLoader","ensure","factory","$injectorMinErr","$$minErr","requires","configFn","invokeLater","provider","method","insertMethod","queue","invokeQueue","moduleInstance","invokeLaterAndSetModuleName","recipeName","factoryFunction","$$moduleName","configBlocks","runBlocks","_invokeQueue","_configBlocks","_runBlocks","service","constant","decorator","animation","filter","directive","component","run","block","shallowCopy","publishExternalAPI","version","uppercase","counter","csp","angularModule","ngModule","$$sanitizeUri","$$SanitizeUriProvider","$CompileProvider","a","htmlAnchorDirective","input","inputDirective","textarea","form","formDirective","script","scriptDirective","select","selectDirective","style","styleDirective","option","optionDirective","ngBind","ngBindDirective","ngBindHtml","ngBindHtmlDirective","ngBindTemplate","ngBindTemplateDirective","ngClass","ngClassDirective","ngClassEven","ngClassEvenDirective","ngClassOdd","ngClassOddDirective","ngCloak","ngCloakDirective","ngController","ngControllerDirective","ngForm","ngFormDirective","ngHide","ngHideDirective","ngIf","ngIfDirective","ngInclude","ngIncludeDirective","ngInit","ngInitDirective","ngNonBindable","ngNonBindableDirective","ngPluralize","ngPluralizeDirective","ngRepeat","ngRepeatDirective","ngShow","ngShowDirective","ngStyle","ngStyleDirective","ngSwitch","ngSwitchDirective","ngSwitchWhen","ngSwitchWhenDirective","ngSwitchDefault","ngSwitchDefaultDirective","ngOptions","ngOptionsDirective","ngTransclude","ngTranscludeDirective","ngModel","ngModelDirective","ngList","ngListDirective","ngChange","ngChangeDirective","pattern","patternDirective","ngPattern","required","requiredDirective","ngRequired","minlength","minlengthDirective","ngMinlength","maxlength","maxlengthDirective","ngMaxlength","ngValue","ngValueDirective","ngModelOptions","ngModelOptionsDirective","ngIncludeFillContentDirective","ngAttributeAliasDirectives","ngEventDirectives","$anchorScroll","$AnchorScrollProvider","$animate","$AnimateProvider","$animateCss","$CoreAnimateCssProvider","$$animateJs","$$CoreAnimateJsProvider","$$animateQueue","$$CoreAnimateQueueProvider","$$AnimateRunner","$$AnimateRunnerFactoryProvider","$$animateAsyncRun","$$AnimateAsyncRunFactoryProvider","$browser","$BrowserProvider","$cacheFactory","$CacheFactoryProvider","$controller","$ControllerProvider","$document","$DocumentProvider","$exceptionHandler","$ExceptionHandlerProvider","$filter","$FilterProvider","$$forceReflow","$$ForceReflowProvider","$interpolate","$InterpolateProvider","$interval","$IntervalProvider","$http","$HttpProvider","$httpParamSerializer","$HttpParamSerializerProvider","$httpParamSerializerJQLike","$HttpParamSerializerJQLikeProvider","$httpBackend","$HttpBackendProvider","$xhrFactory","$xhrFactoryProvider","$location","$LocationProvider","$log","$LogProvider","$parse","$ParseProvider","$rootScope","$RootScopeProvider","$q","$QProvider","$$q","$$QProvider","$sce","$SceProvider","$sceDelegate","$SceDelegateProvider","$sniffer","$SnifferProvider","$templateCache","$TemplateCacheProvider","$templateRequest","$TemplateRequestProvider","$$testability","$$TestabilityProvider","$timeout","$TimeoutProvider","$window","$WindowProvider","$$rAF","$$RAFProvider","$$jqLite","$$jqLiteProvider","$$HashMap","$$HashMapProvider","$$cookieReader","$$CookieReaderProvider","camelCase","SPECIAL_CHARS_REGEXP","_","offset","toUpperCase","MOZ_HACK_REGEXP","jqLiteAcceptsData","NODE_TYPE_ELEMENT","NODE_TYPE_DOCUMENT","jqLiteBuildFragment","tmp","fragment","createDocumentFragment","HTML_REGEXP","appendChild","createElement","TAG_NAME_REGEXP","exec","wrap","wrapMap","_default","innerHTML","XHTML_TAG_REGEXP","lastChild","childNodes","firstChild","textContent","createTextNode","jqLiteWrapNode","wrapper","parentNode","replaceChild","argIsString","trim","jqLiteMinErr","parsed","SINGLE_TAG_REGEXP","jqLiteAddNodes","jqLiteClone","jqLiteDealoc","onlyDescendants","jqLiteRemoveData","querySelectorAll","descendants","l","jqLiteOff","unsupported","expandoStore","jqLiteExpandoStore","handle","removeHandler","listenerFns","removeEventListener","MOUSE_EVENT_MAP","expandoId","ng339","jqCache","createIfNecessary","jqId","jqLiteData","isSimpleSetter","isSimpleGetter","massGetter","jqLiteHasClass","selector","jqLiteRemoveClass","cssClasses","setAttribute","cssClass","jqLiteAddClass","existingClasses","root","elements","jqLiteController","jqLiteInheritedData","documentElement","names","NODE_TYPE_DOCUMENT_FRAGMENT","host","jqLiteEmpty","removeChild","jqLiteRemove","keepData","jqLiteDocumentLoaded","action","win","readyState","setTimeout","getBooleanAttrName","booleanAttr","BOOLEAN_ATTR","BOOLEAN_ELEMENTS","createEventHandler","eventHandler","event","isDefaultPrevented","event.isDefaultPrevented","defaultPrevented","eventFns","eventFnsLength","immediatePropagationStopped","originalStopImmediatePropagation","stopImmediatePropagation","event.stopImmediatePropagation","stopPropagation","isImmediatePropagationStopped","event.isImmediatePropagationStopped","handlerWrapper","specialHandlerWrapper","defaultHandlerWrapper","handler","specialMouseHandlerWrapper","target","related","relatedTarget","jqLiteContains","$get","this.$get","hasClass","classes","addClass","removeClass","hashKey","nextUidFn","objType","HashMap","isolatedUid","this.nextUid","put","extractArgs","fnText","Function","prototype","STRIP_COMMENTS","ARROW_ARG","FN_ARGS","anonFn","args","modulesToLoad","supportObject","delegate","provider_","providerInjector","instantiate","providerCache","providerSuffix","enforceReturnValue","enforcedReturnValue","result","instanceInjector","factoryFn","enforce","loadModules","moduleFn","runInvokeQueue","invokeArgs","loadedModules","message","stack","createInternalInjector","cache","getService","serviceName","caller","INSTANTIATING","err","shift","injectionArgs","locals","$inject","$$annotate","msie","Type","ctor","annotate","has","$injector","instanceCache","decorFn","origProvider","orig$get","origProvider.$get","origInstance","$delegate","protoInstanceInjector","autoScrollingEnabled","disableAutoScrolling","this.disableAutoScrolling","getFirstAnchor","list","some","scrollTo","scrollIntoView","scroll","yOffset","getComputedStyle","position","getBoundingClientRect","bottom","elemTop","top","scrollBy","hash","elm","getElementById","getElementsByName","autoScrollWatch","autoScrollWatchAction","newVal","oldVal","mergeClasses","b","splitClasses","klass","prepareAnimateOptions","options","Browser","completeOutstandingRequest","outstandingRequestCount","outstandingRequestCallbacks","pop","error","cacheStateAndFireUrlChange","pendingLocation","cacheState","fireUrlChange","cachedState","getCurrentState","lastCachedState","lastBrowserUrl","url","lastHistoryState","urlChangeListeners","listener","history","clearTimeout","pendingDeferIds","isMock","$$completeOutstandingRequest","$$incOutstandingRequestCount","self.$$incOutstandingRequestCount","notifyWhenNoOutstandingRequests","self.notifyWhenNoOutstandingRequests","callback","href","baseElement","state","self.url","sameState","sameBase","stripHash","substr","self.state","urlChangeInit","onUrlChange","self.onUrlChange","$$applicationDestroyed","self.$$applicationDestroyed","off","$$checkUrlChange","baseHref","self.baseHref","defer","self.defer","delay","timeoutId","cancel","self.defer.cancel","deferId","cacheFactory","cacheId","refresh","entry","freshEnd","staleEnd","n","link","p","nextEntry","prevEntry","caches","size","stats","id","capacity","Number","MAX_VALUE","lruHash","lruEntry","remove","removeAll","destroy","info","cacheFactory.info","cacheFactory.get","$$sanitizeUriProvider","parseIsolateBindings","directiveName","isController","LOCAL_REGEXP","bindings","definition","scopeName","bindingCache","$compileMinErr","mode","collection","optional","attrName","assertValidDirectiveName","getDirectiveRequire","require","REQUIRE_PREFIX_REGEXP","hasDirectives","COMMENT_DIRECTIVE_REGEXP","CLASS_DIRECTIVE_REGEXP","ALL_OR_NOTHING_ATTRS","EVENT_HANDLER_ATTR_REGEXP","this.directive","registerDirective","directiveFactory","Suffix","directives","priority","restrict","this.component","makeInjectable","tElement","tAttrs","$element","$attrs","template","templateUrl","ddo","controllerAs","identifierForController","transclude","bindToController","aHrefSanitizationWhitelist","this.aHrefSanitizationWhitelist","regexp","imgSrcSanitizationWhitelist","this.imgSrcSanitizationWhitelist","this.debugInfoEnabled","enabled","TTL","onChangesTtl","this.onChangesTtl","flushOnChangesQueue","onChangesQueue","errors","Attributes","attributesToCopy","$attr","$$element","setSpecialAttr","specialAttrHolder","attributes","attribute","removeNamedItem","setNamedItem","safeAddClass","className","$compileNodes","transcludeFn","maxPriority","ignoreDirective","previousCompileContext","NOT_EMPTY","domNode","nodeValue","compositeLinkFn","compileNodes","$$addScopeClass","namespace","publicLinkFn","cloneConnectFn","needsNewScope","$parent","$new","parentBoundTranscludeFn","transcludeControllers","futureParentElement","$$boundTransclude","$linkNode","wrapTemplate","controllerName","instance","$$addScopeInfo","nodeList","$rootElement","childLinkFn","childScope","childBoundTranscludeFn","stableNodeList","nodeLinkFnFound","linkFns","idx","nodeLinkFn","transcludeOnThisElement","createBoundTranscludeFn","templateOnThisElement","attrs","linkFnFound","collectDirectives","applyDirectivesToNode","terminal","previousBoundTranscludeFn","boundTranscludeFn","transcludedScope","cloneFn","controllers","containingScope","$$transcluded","boundSlots","$$slots","slotName","attrsMap","addDirective","directiveNormalize","isNgAttr","nAttrs","attrStartName","attrEndName","ngAttrName","NG_ATTR_BINDING","PREFIX_REGEXP","multiElementMatch","MULTI_ELEMENT_DIR_RE","directiveIsMultiElement","nName","addAttrInterpolateDirective","animVal","addTextInterpolateDirective","NODE_TYPE_COMMENT","byPriority","groupScan","attrStart","attrEnd","depth","groupElementsLinkFnWrapper","linkFn","groupedElementsLink","compilationGenerator","eager","compiled","lazyCompilation","compileNode","templateAttrs","jqCollection","originalReplaceDirective","preLinkFns","postLinkFns","addLinkFns","pre","post","newIsolateScopeDirective","$$isolateScope","cloneAndAnnotateFn","linkNode","controllersBoundTransclude","cloneAttachFn","hasElementTranscludeDirective","elementControllers","slotTranscludeFn","scopeToChild","controllerScope","newScopeDirective","isSlotFilled","transcludeFn.isSlotFilled","controllerDirectives","setupControllers","templateDirective","$$originalDirective","$$isolateBindings","scopeBindingInfo","initializeDirectiveBindings","removeWatches","$on","controllerDirective","$$bindings","bindingInfo","identifier","controllerResult","getControllers","controllerInstance","$onChanges","initialChanges","$onInit","$onDestroy","callOnDestroyHook","invokeLinkFn","$postLink","terminalPriority","nonTlbTranscludeDirective","hasTranscludeDirective","hasTemplate","$compileNode","$template","childTranscludeFn","didScanForMultipleTransclusion","mightHaveMultipleTransclusionError","directiveValue","$$start","$$end","assertNoDuplicate","$$tlb","scanningIndex","candidateDirective","$$createComment","replaceWith","$$parentNode","replaceDirective","slots","contents","slotMap","filledSlots","elementSelector","filled","$$newScope","denormalizeTemplate","removeComments","templateNamespace","newTemplateAttrs","templateDirectives","unprocessedDirectives","markDirectiveScope","mergeTemplateAttributes","compileTemplateUrl","Math","max","inheritType","dataName","property","controllerKey","$scope","$transclude","newScope","tDirectives","startAttrName","endAttrName","multiElement","srcAttr","dstAttr","$set","linkQueue","afterTemplateNodeLinkFn","afterTemplateChildLinkFn","beforeTemplateCompileNode","origAsyncDirective","derivedSyncDirective","then","content","tempTemplateAttrs","beforeTemplateLinkNode","linkRootElement","$$destroyed","oldClasses","delayedNodeLinkFn","ignoreChildLinkFn","diff","what","previousDirective","wrapModuleNameIfDefined","moduleName","text","interpolateFn","textInterpolateCompileFn","templateNode","templateNodeParent","hasCompileParent","$$addBindingClass","textInterpolateLinkFn","$$addBindingInfo","expressions","interpolateFnWatchAction","getTrustedContext","attrNormalizedName","HTML","RESOURCE_URL","allOrNothing","trustedContext","attrInterpolatePreLinkFn","$$observers","newValue","$$inter","$$scope","oldValue","$updateClass","elementsToRemove","newNode","firstElementToRemove","removeCount","j2","hasData","annotation","recordChanges","currentValue","previousValue","$$postDigest","changes","triggerOnChangesHook","SimpleChange","removeWatchCollection","initializeBinding","lastValue","parentGet","parentSet","compare","$observe","_UNINITIALIZED_VALUE","literal","assign","parentValueWatch","parentValue","$stateful","removeWatch","$watchCollection","initialValue","parentValueWatchAction","SIMPLE_ATTR_NAME","$normalize","$addClass","classVal","$removeClass","newClasses","toAdd","tokenDifference","toRemove","writeAttr","booleanKey","aliasedKey","ALIASED_ATTR","observer","trimmedSrcset","srcPattern","rawUris","nbrUrisWith2parts","floor","innerIdx","lastTuple","removeAttr","listeners","startSymbol","endSymbol","binding","isolated","noTemplate","compile.$$createComment","comment","createComment","previous","current","str1","str2","values","tokens1","tokens2","token","jqNodes","ident","CNTRL_REG","globals","this.has","register","this.register","allowGlobals","this.allowGlobals","addIdentifier","expression","later","$controllerMinErr","controllerPrototype","$controllerInit","exception","cause","serializeValue","v","toISOString","ngParamSerializer","params","jQueryLikeParamSerializer","serialize","toSerialize","topLevel","defaultHttpResponseTransform","headers","tempData","JSON_PROTECTION_PREFIX","contentType","jsonStart","JSON_START","JSON_ENDS","parseHeaders","line","headerVal","headerKey","headersGetter","headersObj","transformData","status","fns","defaults","transformResponse","transformRequest","d","common","CONTENT_TYPE_APPLICATION_JSON","patch","xsrfCookieName","xsrfHeaderName","paramSerializer","useApplyAsync","this.useApplyAsync","useLegacyPromise","useLegacyPromiseExtensions","this.useLegacyPromiseExtensions","interceptorFactories","interceptors","requestConfig","response","resp","reject","executeHeaderFns","headerContent","processedHeaders","headerFn","header","mergeHeaders","defHeaders","reqHeaders","defHeaderName","lowercaseDefHeaderName","reqHeaderName","chain","serverRequest","reqData","withCredentials","sendReq","promise","when","reversedInterceptors","interceptor","request","requestError","responseError","thenFn","rejectFn","success","promise.success","promise.error","$httpMinErrLegacyFn","createApplyHandlers","eventHandlers","applyHandlers","callEventHandler","$applyAsync","$$phase","done","headersString","statusText","resolveHttpPromise","resolvePromise","deferred","resolve","resolvePromiseWithResult","removePendingReq","pendingRequests","cachedResp","buildUrl","defaultCache","xsrfValue","urlIsSameOrigin","timeout","responseType","uploadEventHandlers","serializedParams","interceptorFactory","createShortMethods","createShortMethodsWithData","createXhr","XMLHttpRequest","createHttpBackend","callbacks","$browserDefer","rawDocument","jsonpReq","callbackId","async","body","called","addEventListener","timeoutRequest","jsonpDone","xhr","abort","completeRequest","open","setRequestHeader","onload","xhr.onload","responseText","urlResolve","protocol","getAllResponseHeaders","onerror","onabort","upload","send","this.startSymbol","this.endSymbol","escape","ch","unescapeText","escapedStartRegexp","escapedEndRegexp","constantWatchDelegate","objectEquality","constantInterp","unwatch","constantInterpolateWatch","mustHaveExpression","parseStringifyInterceptor","getTrusted","$interpolateMinErr","interr","unescapedText","exp","$$watchDelegate","endIndex","parseFns","textLength","expressionPositions","startSymbolLength","endSymbolLength","throwNoconcat","compute","interpolationFn","$watchGroup","interpolateFnWatcher","oldValues","currValue","$interpolate.startSymbol","$interpolate.endSymbol","interval","count","invokeApply","hasParams","iteration","setInterval","clearInterval","skipApply","$$intervalId","tick","notify","intervals","interval.cancel","encodePath","segments","parseAbsoluteUrl","absoluteUrl","locationObj","parsedUrl","$$protocol","$$host","hostname","$$port","port","DEFAULT_PORTS","parseAppUrl","relativeUrl","prefixed","$$path","pathname","$$search","search","$$hash","stripBaseUrl","base","lastIndexOf","trimEmptyHash","LocationHtml5Url","appBase","appBaseNoFile","basePrefix","$$html5","$$parse","this.$$parse","pathUrl","$locationMinErr","$$compose","this.$$compose","$$url","$$absUrl","$$parseLinkUrl","this.$$parseLinkUrl","relHref","appUrl","prevAppUrl","rewrittenUrl","LocationHashbangUrl","hashPrefix","withoutBaseUrl","withoutHashUrl","windowsFilePathExp","firstPathSegmentMatch","LocationHashbangInHtml5Url","locationGetter","locationGetterSetter","preprocess","html5Mode","requireBase","rewriteLinks","this.hashPrefix","this.html5Mode","setBrowserUrlWithFallback","oldUrl","oldState","$$state","afterLocationChange","$broadcast","absUrl","LocationMode","initialUrl","IGNORE_URI_REGEXP","ctrlKey","metaKey","shiftKey","which","button","absHref","preventDefault","initializing","newUrl","newState","$digest","$locationWatch","currentReplace","$$replace","urlOrStateChanged","debug","debugEnabled","this.debugEnabled","flag","formatError","Error","sourceURL","consoleLog","console","logFn","log","hasApply","arg1","arg2","warn","ensureSafeMemberName","fullExpression","$parseMinErr","getStringValue","ensureSafeObject","children","ensureSafeFunction","CALL","APPLY","BIND","ensureSafeAssignContext","ifDefined","plusFn","r","findConstantAndWatchExpressions","ast","allConstants","argsToWatch","AST","Program","expr","Literal","toWatch","UnaryExpression","argument","BinaryExpression","left","right","LogicalExpression","ConditionalExpression","alternate","consequent","Identifier","MemberExpression","object","computed","CallExpression","callee","AssignmentExpression","ArrayExpression","ObjectExpression","properties","ThisExpression","LocalsExpression","getInputs","lastExpression","isAssignable","assignableAST","NGValueParameter","operator","isLiteral","ASTCompiler","astBuilder","ASTInterpreter","isPossiblyDangerousMemberName","getValueOf","objectValueOf","cacheDefault","cacheExpensive","literals","identStart","identContinue","addLiteral","this.addLiteral","literalName","literalValue","setIdentifierFns","this.setIdentifierFns","identifierStart","identifierContinue","interceptorFn","expensiveChecks","parsedExpression","oneTime","cacheKey","runningChecksEnabled","parseOptions","$parseOptionsExpensive","$parseOptions","lexer","Lexer","parser","Parser","oneTimeLiteralWatchDelegate","oneTimeWatchDelegate","inputs","inputsWatchDelegate","expensiveChecksInterceptor","addInterceptor","expensiveCheckFn","expensiveCheckOldValue","expressionInputDirtyCheck","oldValueOfValue","prettyPrintExpression","inputExpressions","lastResult","oldInputValueOf","expressionInputWatch","newInputValue","oldInputValueOfValues","oldInputValues","expressionInputsWatch","changed","oneTimeWatch","oneTimeListener","old","isAllDefined","allDefined","constantWatch","watchDelegate","useInputs","regularInterceptedExpression","oneTimeInterceptedExpression","noUnsafeEval","isIdentifierStart","isIdentifierContinue","$$runningExpensiveChecks","$parse.$$runningExpensiveChecks","qFactory","nextTick","exceptionHandler","Promise","simpleBind","scheduleProcessQueue","processScheduled","pending","Deferred","$qMinErr","TypeError","onFulfilled","onRejected","progressBack","catch","finally","handleCallback","$$reject","$$resolve","that","rejectPromise","progress","makePromise","resolved","isResolved","callbackOutput","errback","$Q","resolver","resolveFn","all","promises","results","requestAnimationFrame","webkitRequestAnimationFrame","cancelAnimationFrame","webkitCancelAnimationFrame","webkitCancelRequestAnimationFrame","rafSupported","raf","timer","supported","createChildScopeClass","ChildScope","$$watchers","$$nextSibling","$$childHead","$$childTail","$$listeners","$$listenerCount","$$watchersCount","$id","$$ChildScope","$rootScopeMinErr","lastDirtyWatch","applyAsyncId","digestTtl","this.digestTtl","destroyChildScope","$event","currentScope","cleanUpScope","$$prevSibling","$root","Scope","beginPhase","phase","incrementWatchersCount","decrementListenerCount","initWatchVal","flushApplyAsync","applyAsyncQueue","scheduleApplyAsync","isolate","child","watchExp","watcher","last","eq","deregisterWatch","watchExpressions","watchGroupAction","changeReactionScheduled","firstRun","newValues","deregisterFns","shouldCall","deregisterWatchGroup","unwatchFn","watchGroupSubAction","$watchCollectionInterceptor","_value","bothNaN","newItem","oldItem","internalArray","oldLength","changeDetected","newLength","internalObject","veryOldValue","trackVeryOldValue","changeDetector","initRun","$watchCollectionAction","watch","watchers","dirty","ttl","watchLog","logIdx","asyncTask","asyncQueuePosition","asyncQueue","$eval","msg","next","postDigestQueuePosition","postDigestQueue","eventName","this.$watchGroup","$applyAsyncExpression","namedListeners","indexOfListener","$emit","targetScope","listenerArgs","$$asyncQueue","$$postDigestQueue","$$applyAsyncQueue","sanitizeUri","uri","isImage","regex","normalizedVal","adjustMatcher","matcher","$sceMinErr","escapeForRegexp","adjustMatchers","matchers","adjustedMatchers","SCE_CONTEXTS","resourceUrlWhitelist","resourceUrlBlacklist","this.resourceUrlWhitelist","this.resourceUrlBlacklist","matchUrl","generateHolderType","Base","holderType","trustedValue","$$unwrapTrustedValue","this.$$unwrapTrustedValue","holderType.prototype.valueOf","holderType.prototype.toString","htmlSanitizer","trustedValueHolderBase","byType","CSS","URL","JS","trustAs","Constructor","maybeTrusted","allowed","this.enabled","sce","isEnabled","sce.isEnabled","sce.getTrusted","parseAs","sce.parseAs","enumValue","lName","eventSupport","hasHistoryPushState","chrome","app","runtime","pushState","android","userAgent","navigator","boxee","vendorPrefix","vendorRegex","bodyStyle","transitions","animations","webkitTransition","webkitAnimation","hasEvent","divElm","httpOptions","this.httpOptions","handleRequestFn","tpl","ignoreRequestError","totalPendingRequests","getTrustedResourceUrl","transformer","handleError","$templateRequestMinErr","testability","testability.findBindings","opt_exactMatch","getElementsByClassName","matches","dataBinding","bindingName","testability.findModels","prefixes","attributeEquals","testability.getLocation","testability.setLocation","testability.whenStable","deferreds","$$timeoutId","timeout.cancel","urlParsingNode","requestUrl","originUrl","$$CookieReader","safeDecodeURIComponent","lastCookies","lastCookieString","cookieArray","cookie","currentCookieString","filters","suffix","currencyFilter","dateFilter","filterFilter","jsonFilter","limitToFilter","lowercaseFilter","numberFilter","orderByFilter","uppercaseFilter","comparator","matchAgainstAnyProp","getTypeForFilter","expressionType","predicateFn","createPredicateFn","shouldMatchPrimitives","actual","expected","deepCompare","dontMatchWholeObject","actualType","expectedType","expectedVal","matchAnyProperty","actualVal","$locale","formats","NUMBER_FORMATS","amount","currencySymbol","fractionSize","CURRENCY_SYM","PATTERNS","maxFrac","formatNumber","GROUP_SEP","DECIMAL_SEP","number","numStr","exponent","digits","numberOfIntegerDigits","zeros","ZERO_CHAR","MAX_DIGITS","roundNumber","parsedNumber","minFrac","fractionLen","min","roundAt","digit","k","carry","reduceRight","groupSep","decimalSep","isInfinity","isFinite","isZero","abs","formattedText","integerLen","decimals","reduce","groups","lgSize","gSize","negPre","negSuf","posPre","posSuf","padNumber","num","negWrap","neg","dateGetter","dateStrGetter","shortForm","standAlone","getFirstThursdayOfYear","year","dayOfWeekOnFirst","getDay","weekGetter","firstThurs","getFullYear","thisThurs","getMonth","getDate","round","eraGetter","ERAS","jsonStringToDate","string","R_ISO8601_STR","tzHour","tzMin","dateSetter","setUTCFullYear","setFullYear","timeSetter","setUTCHours","setHours","m","s","ms","parseFloat","format","DATETIME_FORMATS","NUMBER_STRING","DATE_FORMATS_SPLIT","DATE_FORMATS","spacing","limit","begin","Infinity","sliceFn","end","processPredicates","sortPredicates","map","predicate","descending","defaultCompare","v1","v2","type1","type2","value1","value2","sortPredicate","reverseOrder","compareFn","predicates","compareValues","getComparisonObject","tieBreaker","predicateValues","doComparison","ngDirective","FormController","controls","$error","$$success","$pending","$name","$dirty","$pristine","$valid","$invalid","$submitted","$$parentForm","nullFormCtrl","$rollbackViewValue","form.$rollbackViewValue","control","$commitViewValue","form.$commitViewValue","$addControl","form.$addControl","$$renameControl","form.$$renameControl","newName","oldName","$removeControl","form.$removeControl","$setValidity","addSetValidityMethod","ctrl","unset","$setDirty","form.$setDirty","PRISTINE_CLASS","DIRTY_CLASS","$setPristine","form.$setPristine","setClass","SUBMITTED_CLASS","$setUntouched","form.$setUntouched","$setSubmitted","form.$setSubmitted","stringBasedInputType","$formatters","$isEmpty","baseInputType","composing","ev","ngTrim","$viewValue","$$hasNativeValidators","$setViewValue","deferListener","origValue","keyCode","PARTIAL_VALIDATION_TYPES","PARTIAL_VALIDATION_EVENTS","validity","origBadInput","badInput","origTypeMismatch","typeMismatch","$render","ctrl.$render","createDateParser","mapping","iso","ISO_DATE_REGEXP","yyyy","MM","dd","HH","getHours","mm","ss","getSeconds","sss","getMilliseconds","part","NaN","createDateInputType","parseDate","dynamicDateInputType","isValidDate","parseObservedDateValue","badInputChecker","$options","previousDate","$$parserName","$parsers","parsedDate","ngModelMinErr","ngMin","minVal","$validators","ctrl.$validators.min","$validate","ngMax","maxVal","ctrl.$validators.max","VALIDITY_STATE_PROPERTY","parseConstantExpr","parseFn","classDirective","arrayDifference","arrayClasses","addClasses","digestClassCounts","classCounts","classesToUpdate","updateClasses","ngClassWatchAction","$index","old$index","mod","cachedToggleClass","switchValue","classCache","toggleValidationCss","validationErrorKey","isValid","VALID_CLASS","INVALID_CLASS","setValidity","isObjectEmpty","PENDING_CLASS","combinedState","REGEX_STRING_REGEXP","documentMode","rules","ngCspElement","ngCspAttribute","noInlineStyle","name_","el","full","major","minor","dot","codeName","expando","JQLite._data","mouseleave","mouseenter","optgroup","tbody","tfoot","colgroup","caption","thead","th","td","Node","contains","compareDocumentPosition","ready","trigger","fired","removeData","jqLiteHasData","jqLiteCleanData","removeAttribute","css","NODE_TYPE_ATTRIBUTE","lowercasedName","specified","getNamedItem","ret","getText","$dv","multiple","selected","nodeCount","jqLiteOn","types","addHandler","noEventListener","one","onFn","replaceNode","insertBefore","contentDocument","prepend","wrapNode","detach","after","newElement","toggleClass","condition","classCondition","nextElementSibling","getElementsByTagName","extraParameters","dummyEvent","handlerArgs","eventFnsCopy","arg3","unbind","FN_ARG_SPLIT","FN_ARG","argDecl","underscore","$animateMinErr","postDigestElements","updateData","handleCSSClassChanges","existing","pin","domOperation","from","to","classesAdded","add","classesRemoved","runner","complete","$$registeredAnimations","classNameFilter","this.classNameFilter","$$classNameFilter","reservedRegex","NG_ANIMATE_CLASSNAME","domInsert","parentElement","afterElement","afterNode","ELEMENT_NODE","previousElementSibling","enter","move","leave","addclass","animate","tempClasses","waitForTick","waitQueue","passed","AnimateRunner","setHost","rafTick","_doneCallbacks","_tick","this._tick","doc","hidden","_state","AnimateRunner.chain","AnimateRunner.all","runners","onProgress","DONE_COMPLETE_STATE","getPromise","resolveHandler","rejectHandler","pause","resume","_resolve","INITIAL_STATE","DONE_PENDING_STATE","initialOptions","closed","$$prepared","cleanupStyles","start","UNINITIALIZED_VALUE","isFirstChange","SimpleChange.prototype.isFirstChange","offsetWidth","APPLICATION_JSON","$httpMinErr","$interpolateMinErr.throwNoconcat","$interpolateMinErr.interr","PATH_MATCH","locationPrototype","paramValue","Location","Location.prototype.state","OPERATORS","ESCAPE","lex","tokens","readString","peek","readNumber","peekMultichar","readIdent","is","isWhitespace","ch2","ch3","op2","op3","op1","throwError","chars","codePointAt","isValidIdentifierStart","isValidIdentifierContinue","cp","charCodeAt","cp1","cp2","isExpOperator","colStr","peekCh","quote","rawString","hex","String","fromCharCode","rep","ExpressionStatement","Property","program","expressionStatement","expect","filterChain","assignment","ternary","logicalOR","consume","logicalAND","equality","relational","additive","multiplicative","unary","primary","arrayDeclaration","selfReferential","parseArguments","baseExpression","peekToken","kind","e1","e2","e3","e4","peekAhead","t","nextId","vars","own","assignable","stage","computing","recurse","return_","generateFunction","fnKey","intoId","watchId","fnString","USE","STRICT","filterPrefix","watchFns","varsPrefix","section","nameId","recursionFn","skipWatchIdCheck","if_","lazyAssign","computedMember","lazyRecurse","plus","not","getHasOwnProperty","nonComputedMember","addEnsureSafeObject","notNull","addEnsureSafeAssignContext","addEnsureSafeMemberName","addEnsureSafeFunction","member","filterName","defaultValue","UNSAFE_CHARACTERS","SAFE_IDENTIFIER","stringEscapeFn","stringEscapeRegex","c","skip","init","fn.assign","rhs","lhs","unary+","unary-","unary!","binary+","binary-","binary*","binary/","binary%","binary===","binary!==","binary==","binary!=","binary<","binary>","binary<=","binary>=","binary&&","binary||","ternary?:","astCompiler","yy","y","MMMM","MMM","M","LLLL","H","hh","EEEE","EEE","ampmGetter","AMPMS","Z","timeZoneGetter","zone","paddedZone","ww","w","G","GG","GGG","GGGG","longEraGetter","ERANAMES","xlinkHref","propName","defaultLinkFn","normalized","ngBooleanAttrWatchAction","htmlAttr","ngAttrAliasWatchAction","nullFormRenameControl","formDirectiveFactory","isNgForm","getSetter","ngFormCompile","formElement","nameAttr","ngFormPreLink","ctrls","handleFormSubmission","setter","URL_REGEXP","EMAIL_REGEXP","NUMBER_REGEXP","DATE_REGEXP","DATETIMELOCAL_REGEXP","WEEK_REGEXP","MONTH_REGEXP","TIME_REGEXP","inputType","textInputType","weekParser","isoWeek","existingDate","week","hours","seconds","milliseconds","addDays","numberInputType","urlInputType","ctrl.$validators.url","modelValue","viewValue","emailInputType","email","ctrl.$validators.email","radioInputType","checked","checkboxInputType","trueValue","ngTrueValue","falseValue","ngFalseValue","ctrl.$isEmpty","CONSTANT_VALUE_REGEXP","tplAttr","ngValueConstantLink","ngValueLink","valueWatchAction","$compile","ngBindCompile","templateElement","ngBindLink","ngBindWatchAction","ngBindTemplateCompile","ngBindTemplateLink","ngBindHtmlCompile","ngBindHtmlGetter","ngBindHtmlWatch","sceValueOf","ngBindHtmlLink","ngBindHtmlWatchAction","getTrustedHtml","$viewChangeListeners","forceAsyncEvents","ngEventHandler","previousElements","ngIfWatchAction","srcExp","onloadExp","autoScrollExp","autoscroll","changeCounter","previousElement","currentElement","cleanupLastIncludeContent","ngIncludeWatchAction","afterAnimation","thisChangeId","namespaceAdaptedClone","trimValues","NgModelController","$modelValue","$$rawModelValue","$asyncValidators","$untouched","$touched","parsedNgModel","parsedNgModelAssign","ngModelGet","ngModelSet","pendingDebounce","parserValid","$$setOptions","this.$$setOptions","getterSetter","invokeModelGetter","invokeModelSetter","$$$p","this.$isEmpty","$$updateEmptyClasses","this.$$updateEmptyClasses","NOT_EMPTY_CLASS","EMPTY_CLASS","currentValidationRunId","this.$setPristine","this.$setDirty","this.$setUntouched","UNTOUCHED_CLASS","TOUCHED_CLASS","$setTouched","this.$setTouched","this.$rollbackViewValue","$$lastCommittedViewValue","this.$validate","prevValid","prevModelValue","allowInvalid","$$runValidators","allValid","$$writeModelToScope","this.$$runValidators","doneCallback","processSyncValidators","syncValidatorsValid","validator","processAsyncValidators","validatorPromises","validationDone","localValidationRunId","processParseErrors","errorKey","this.$commitViewValue","$$parseAndValidate","this.$$parseAndValidate","this.$$writeModelToScope","this.$setViewValue","updateOnDefault","$$debounceViewValueCommit","this.$$debounceViewValueCommit","debounceDelay","debounce","ngModelWatch","formatters","ngModelCompile","ngModelPreLink","modelCtrl","formCtrl","ngModelPostLink","updateOn","DEFAULT_REGEXP","ngOptionsMinErr","NG_OPTIONS_REGEXP","parseOptionsExpression","optionsExp","selectElement","Option","selectValue","label","group","disabled","getOptionValuesKeys","optionValues","optionValuesKeys","keyName","itemKey","valueName","selectAs","trackBy","viewValueFn","trackByFn","getTrackByValueFn","getHashOfValue","getTrackByValue","getLocals","displayFn","groupByFn","disableWhenFn","valuesFn","getWatchables","watchedArray","optionValuesLength","disableWhen","getOptions","optionItems","selectValueMap","optionItem","getOptionFromViewValue","getViewValueFromOption","optionTemplate","optGroupTemplate","ngOptionsPreLink","registerOption","ngOptionsPostLink","updateOptionElement","updateOptions","selectCtrl","readValue","groupElementMap","providedEmptyOption","emptyOption","addOption","groupElement","listFragment","optionElement","ngModelCtrl","nextValue","unknownOption","ngModelCtrl.$isEmpty","writeValue","selectCtrl.writeValue","selectCtrl.readValue","selectedValues","selections","selectedOption","BRACE","IS_WHEN","updateElementText","newText","numberExp","whenExp","whens","whensExpFns","braceReplacement","watchRemover","lastCount","attributeName","tmpMatch","whenKey","ngPluralizeWatchAction","countIsNaN","pluralCat","whenExpFn","ngRepeatMinErr","updateScope","valueIdentifier","keyIdentifier","arrayLength","$first","$last","$middle","$odd","$even","ngRepeatCompile","ngRepeatEndComment","aliasAs","trackByExp","trackByExpGetter","trackByIdExpFn","trackByIdArrayFn","trackByIdObjFn","hashFnLocals","ngRepeatLink","lastBlockMap","ngRepeatAction","previousNode","nextNode","nextBlockMap","collectionLength","trackById","collectionKeys","nextBlockOrder","trackByIdFn","blockKey","ngRepeatTransclude","ngShowWatchAction","NG_HIDE_CLASS","NG_HIDE_IN_PROGRESS_CLASS","ngHideWatchAction","ngStyleWatchAction","newStyles","oldStyles","ngSwitchController","cases","selectedTranscludes","selectedElements","previousLeaveAnimations","selectedScopes","spliceFactory","ngSwitchWatchAction","selectedTransclude","caseElement","selectedScope","anchor","ngTranscludeMinErr","ngTranscludeCloneAttachFn","ngTranscludeSlot","noopNgModelController","SelectController","optionsMap","renderUnknownOption","self.renderUnknownOption","unknownVal","removeUnknownOption","self.removeUnknownOption","self.readValue","self.writeValue","hasOption","self.addOption","removeOption","self.removeOption","self.hasOption","self.registerOption","optionScope","optionAttrs","interpolateValueFn","interpolateTextFn","valueAttributeObserveAction","interpolateWatchAction","selectPreLink","lastView","lastViewRef","selectMultipleWatch","selectPostLink","ngModelCtrl.$render","selectCtrlName","ctrl.$validators.required","patternExp","ctrl.$validators.pattern","intVal","ctrl.$validators.maxlength","ctrl.$validators.minlength","getDecimals","opt_precision","pow","ONE","OTHER","$$csp","head"] -} diff --git a/spring-rest-angular/src/main/webapp/resources/vendor/jquery/jquery.min.js b/spring-rest-angular/src/main/webapp/resources/vendor/jquery/jquery.min.js deleted file mode 100644 index 88ed04cce7..0000000000 --- a/spring-rest-angular/src/main/webapp/resources/vendor/jquery/jquery.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v3.0.0 | (c) jQuery Foundation | jquery.org/license */ -!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.0.0",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return a&&"[object Object]"===k.call(a)?(b=e(a))?(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n):!0:!1},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;d>f;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;return"string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a)?(d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e):void 0},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"===c||r.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\x00-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,ca=function(a,b){return b?"\x00"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"label"in b&&b.disabled===a||"form"in b&&b.disabled===a||"form"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&("label"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[0>c?c+b:c]}),even:pa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e)}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,e>i&&ya(a.slice(i,e)),f>e&&ya(a=a.slice(e)),f>e&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;d>b;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;d>b;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(f>b)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(1>=b&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){ - return j.call(r(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:X.test(c)?JSON.parse(c):c}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),Z(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=Z(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthf;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=V.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&ba(d)&&(e[f]=fa(d))):"none"!==c&&(e[f]="none",V.set(d,"display",c)));for(f=0;g>f;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ga(this,!0)},hide:function(){return ga(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){ba(this)?r(this).show():r(this).hide()})}});var ha=/^(?:checkbox|radio)$/i,ia=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,ja=/^$|\/(?:java|ecma)script/i,ka={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;d>c;c++)V.set(a[c],"globalEval",!b||V.get(b[c],"globalEval"))}var na=/<|&#?\w+;/;function oa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;o>n;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(na.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ia.exec(f)||["",""])[1].toLowerCase(),i=ka[h]||ka._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),"script"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;cc;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?r(e,this).index(i)>-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h\x20\t\r\n\f]*)[^>]*)\/>/gi,ya=/\s*$/g;function Ca(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ga(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ha.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ha(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,"script"),Da),i=h.length;m>l;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,la(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ea),l=0;i>l;l++)j=h[l],ja.test(j.type||"")&&!V.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ba,""),k))}return a}function Ia(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(la(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&ma(la(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(xa,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;e>d;d++)Ga(f[d],g[d]);if(b)if(c)for(f=f||la(a),g=g||la(h),d=0,e=f.length;e>d;d++)Fa(f[d],g[d]);else Fa(a,h);return g=la(h,"script"),g.length>0&&ma(g,!i&&la(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!ya.test(a)&&!ka[(ia.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(la(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(la(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;f>=g;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ja=/^margin/,Ka=new RegExp("^("+$+")(?!px)[a-z%]+$","i"),La=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",pa.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,pa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Ma(a,b,c){var d,e,f,g,h=a.style;return c=c||La(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ka.test(g)&&Ja.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Na(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Oa=/^(none|table(?!-c[ea]).+)/,Pa={position:"absolute",visibility:"hidden",display:"block"},Qa={letterSpacing:"0",fontWeight:"400"},Ra=["Webkit","Moz","ms"],Sa=d.createElement("div").style;function Ta(a){if(a in Sa)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ra.length;while(c--)if(a=Ra[c]+b,a in Sa)return a}function Ua(a,b,c){var d=_.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Va(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=r.css(a,c+aa[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+aa[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+aa[f]+"Width",!0,e))):(g+=r.css(a,"padding"+aa[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+aa[f]+"Width",!0,e)));return g}function Wa(a,b,c){var d,e=!0,f=La(a),g="border-box"===r.css(a,"boxSizing",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),0>=d||null==d){if(d=Ma(a,b,f),(0>d||null==d)&&(d=a.style[b]),Ka.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Va(a,b,c||(g?"border":"content"),e,f)+"px"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ma(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=_.exec(c))&&e[1]&&(c=da(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Ma(a,b,d)),"normal"===e&&b in Qa&&(e=Qa[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){return c?!Oa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?Wa(a,b,d):ca(a,Pa,function(){return Wa(a,b,d)}):void 0},set:function(a,c,d){var e,f=d&&La(a),g=d&&Va(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=_.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ua(a,c,g)}}}),r.cssHooks.marginLeft=Na(o.reliableMarginLeft,function(a,b){return b?(parseFloat(Ma(a,"marginLeft"))||a.getBoundingClientRect().left-ca(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px":void 0}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+aa[d]+b]=f[d]||f[d-2]||f[0];return e}},Ja.test(a)||(r.cssHooks[a+b].set=Ua)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=La(a),e=b.length;e>g;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=aa[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function eb(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&ba(a),q=V.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],$a.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ga([a],!0),j=a.style.display||j,k=r.css(a,"display"),ga([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=V.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ga([a],!0),m.done(function(){p||ga([a]),V.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=db(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function fb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function gb(a,b,c){var d,e,f=0,g=gb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Ya||bb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Ya||bb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(fb(k,j.opts.specialEasing);g>f;f++)if(d=gb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,db,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(gb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return da(c.elem,a,_.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(K);for(var c,d=0,e=a.length;e>d;d++)c=a[d],gb.tweeners[c]=gb.tweeners[c]||[],gb.tweeners[c].unshift(b)},prefilters:[eb],prefilter:function(a,b){b?gb.prefilters.unshift(a):gb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:e.duration="number"==typeof e.duration?e.duration:e.duration in r.fx.speeds?r.fx.speeds[e.duration]:r.fx.speeds._default,null!=e.queue&&e.queue!==!0||(e.queue="fx"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ba).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=gb(this,r.extend({},a),f);(e||V.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&_a.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=V.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(cb(b,!0),a,d,e)}}),r.each({slideDown:cb("show"),slideUp:cb("hide"),slideToggle:cb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Ya=r.now();b1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c); -}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\t\r\n\f]/g;function mb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=mb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(c)+" ").replace(lb," ").indexOf(b)>-1)return!0;return!1}});var nb=/\r/g,ob=/[\x20\t\r\n\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(nb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:r.trim(r.text(a)).replace(ob," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){return r.isArray(b)?a.checked=r.inArray(r(a).val(),b)>-1:void 0}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?r.event.trigger(a,b,c,!0):void 0}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,""),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&300>b||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",0>b&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;return o.cors||Pb&&!b.crossDomain?{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}:void 0}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" + + + + + +
    +
    +

    Login

    +

    + +
    + + + + +

    + + + +

    + + +
    +
    +
    + + + \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyauthority.html b/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyauthority.html new file mode 100644 index 0000000000..c62a111ebc --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyauthority.html @@ -0,0 +1,24 @@ + + + + +Protected By Authority + + + +
    +

    Protected By Authority

    +
    + + + + diff --git a/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbynothing.html b/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbynothing.html new file mode 100644 index 0000000000..a6cd0666db --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbynothing.html @@ -0,0 +1,21 @@ + + + + +Protected By Nothing + + + +
    +

    Protected By Nothing

    +
    + + + + diff --git a/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyrole.html b/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyrole.html new file mode 100644 index 0000000000..f4bac55b55 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/templates/rolesauthorities/protectedbyrole.html @@ -0,0 +1,24 @@ + + + + +Protected By Role + + + +
    +

    Protected By Role

    +
    + + + + diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..cf1ac7de89 --- /dev/null +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclIntegrationTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclIntegrationTest.java new file mode 100644 index 0000000000..38e1a2a9e7 --- /dev/null +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclIntegrationTest.java @@ -0,0 +1,119 @@ +package org.baeldung.acl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; + +import org.baeldung.acl.persistence.dao.NoticeMessageRepository; +import org.baeldung.acl.persistence.entity.NoticeMessage; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; +import org.springframework.test.context.support.DirtiesContextTestExecutionListener; +import org.springframework.test.context.transaction.TransactionalTestExecutionListener; +import org.springframework.test.context.web.ServletTestExecutionListener; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestExecutionListeners(listeners={ServletTestExecutionListener.class, + DependencyInjectionTestExecutionListener.class, + DirtiesContextTestExecutionListener.class, + TransactionalTestExecutionListener.class, + WithSecurityContextTestExecutionListener.class}) +public class SpringAclIntegrationTest extends AbstractJUnit4SpringContextTests{ + + private static Integer FIRST_MESSAGE_ID = 1; + private static Integer SECOND_MESSAGE_ID = 2; + private static Integer THIRD_MESSAGE_ID = 3; + private static String EDITTED_CONTENT = "EDITED"; + + @Configuration + @ComponentScan("org.baeldung.acl.*") + public static class SpringConfig { + + } + + @Autowired + NoticeMessageRepository repo; + + @Test + @WithMockUser(username="manager") + public void givenUsernameManager_whenFindAllMessage_thenReturnFirstMessage(){ + List details = repo.findAll(); + assertNotNull(details); + assertEquals(1,details.size()); + assertEquals(FIRST_MESSAGE_ID,details.get(0).getId()); + } + + @Test + @WithMockUser(username="manager") + public void givenUsernameManager_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenOK(){ + NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID); + assertNotNull(firstMessage); + assertEquals(FIRST_MESSAGE_ID,firstMessage.getId()); + + firstMessage.setContent(EDITTED_CONTENT); + repo.save(firstMessage); + + NoticeMessage editedFirstMessage = repo.findById(FIRST_MESSAGE_ID); + assertNotNull(editedFirstMessage); + assertEquals(FIRST_MESSAGE_ID,editedFirstMessage.getId()); + assertEquals(EDITTED_CONTENT,editedFirstMessage.getContent()); + } + + @Test + @WithMockUser(username="hr") + public void givenUsernameHr_whenFindMessageById2_thenOK(){ + NoticeMessage secondMessage = repo.findById(SECOND_MESSAGE_ID); + assertNotNull(secondMessage); + assertEquals(SECOND_MESSAGE_ID,secondMessage.getId()); + } + + @Test(expected=AccessDeniedException.class) + @WithMockUser(username="hr") + public void givenUsernameHr_whenUpdateMessageWithId2_thenFail(){ + NoticeMessage secondMessage = new NoticeMessage(); + secondMessage.setId(SECOND_MESSAGE_ID); + secondMessage.setContent(EDITTED_CONTENT); + repo.save(secondMessage); + } + + @Test + @WithMockUser(roles={"EDITOR"}) + public void givenRoleEditor_whenFindAllMessage_thenReturnThreeMessage(){ + List details = repo.findAll(); + assertNotNull(details); + assertEquals(3,details.size()); + } + + @Test + @WithMockUser(roles={"EDITOR"}) + public void givenRoleEditor_whenUpdateThirdMessage_thenOK(){ + NoticeMessage thirdMessage = new NoticeMessage(); + thirdMessage.setId(THIRD_MESSAGE_ID); + thirdMessage.setContent(EDITTED_CONTENT); + repo.save(thirdMessage); + } + + @Test(expected=AccessDeniedException.class) + @WithMockUser(roles={"EDITOR"}) + public void givenRoleEditor_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenFail(){ + NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID); + assertNotNull(firstMessage); + assertEquals(FIRST_MESSAGE_ID,firstMessage.getId()); + firstMessage.setContent(EDITTED_CONTENT); + repo.save(firstMessage); + } +} + \ No newline at end of file diff --git a/spring-security-mvc-custom/README.md b/spring-security-mvc-custom/README.md index 14bac6c454..2c0be4768e 100644 --- a/spring-security-mvc-custom/README.md +++ b/spring-security-mvc-custom/README.md @@ -8,7 +8,10 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com ### Relevant Articles: - [Spring Security Remember Me](http://www.baeldung.com/spring-security-remember-me) - [Redirect to different pages after Login with Spring Security](http://www.baeldung.com/spring_redirect_after_login) - +- [Changing Spring Model Parameters with Handler Interceptor](http://www.baeldung.com/spring-model-parameters-with-handler-interceptor) +- [Introduction to Spring MVC HandlerInterceptor](http://www.baeldung.com/spring-mvc-handlerinterceptor) +- [Using a Custom Spring MVC’s Handler Interceptor to Manage Sessions](http://www.baeldung.com/spring-mvc-custom-handler-interceptor) +- [A Guide to CSRF Protection in Spring Security](http://www.baeldung.com/spring-security-csrf) ### Build the Project ``` diff --git a/spring-security-mvc-custom/pom.xml b/spring-security-mvc-custom/pom.xml index 4a7e9419cc..805792b795 100644 --- a/spring-security-mvc-custom/pom.xml +++ b/spring-security-mvc-custom/pom.xml @@ -113,6 +113,40 @@ + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + com.google.guava + guava + ${guava.version} + + + + + + org.springframework + spring-test + ${org.springframework.version} + test + + + + org.springframework.security + spring-security-test + ${org.springframework.security.version} + test + @@ -174,7 +208,8 @@ 19.0 3.5 - + 2.9.1 + 4.5.2 4.4.5 diff --git a/spring-security-mvc-custom/src/main/java/org/baeldung/spring/MvcConfig.java b/spring-security-mvc-custom/src/main/java/org/baeldung/spring/MvcConfig.java index 2229516633..3b97afc22d 100644 --- a/spring-security-mvc-custom/src/main/java/org/baeldung/spring/MvcConfig.java +++ b/spring-security-mvc-custom/src/main/java/org/baeldung/spring/MvcConfig.java @@ -1,9 +1,14 @@ package org.baeldung.spring; +import org.baeldung.web.interceptor.LoggerInterceptor; +import org.baeldung.web.interceptor.SessionTimerInterceptor; +import org.baeldung.web.interceptor.UserInterceptor; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; @@ -11,6 +16,7 @@ import org.springframework.web.servlet.view.JstlView; @EnableWebMvc @Configuration +@ComponentScan("org.baeldung.web.controller") public class MvcConfig extends WebMvcConfigurerAdapter { public MvcConfig() { @@ -28,6 +34,7 @@ public class MvcConfig extends WebMvcConfigurerAdapter { registry.addViewController("/login.html"); registry.addViewController("/homepage.html"); registry.addViewController("/console.html"); + registry.addViewController("/csrfHome.html"); } @Bean @@ -40,4 +47,11 @@ public class MvcConfig extends WebMvcConfigurerAdapter { return bean; } + + @Override + public void addInterceptors(final InterceptorRegistry registry) { + registry.addInterceptor(new LoggerInterceptor()); + registry.addInterceptor(new UserInterceptor()); + registry.addInterceptor(new SessionTimerInterceptor()); + } } \ No newline at end of file diff --git a/spring-security-rest-full/src/main/java/org/baeldung/web/controller/BankController.java b/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/BankController.java similarity index 97% rename from spring-security-rest-full/src/main/java/org/baeldung/web/controller/BankController.java rename to spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/BankController.java index e87d5f3dd4..1a4322c611 100644 --- a/spring-security-rest-full/src/main/java/org/baeldung/web/controller/BankController.java +++ b/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/BankController.java @@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; // to test csrf @Controller -@RequestMapping(value = "/auth/") public class BankController { private final Logger logger = LoggerFactory.getLogger(getClass()); diff --git a/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/FooController.java b/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/FooController.java new file mode 100644 index 0000000000..5a3c85d220 --- /dev/null +++ b/spring-security-mvc-custom/src/main/java/org/baeldung/web/controller/FooController.java @@ -0,0 +1,59 @@ +package org.baeldung.web.controller; + +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; + +import java.util.Arrays; +import java.util.List; + +import javax.servlet.http.HttpServletResponse; + +import org.baeldung.web.dto.Foo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.util.UriComponentsBuilder; + +@Controller +@RequestMapping(value = "/auth/foos") +public class FooController { + + @Autowired + private ApplicationEventPublisher eventPublisher; + + public FooController() { + super(); + } + + // API + + // read - single + + @RequestMapping(value = "/{id}", method = RequestMethod.GET) + @ResponseBody + public Foo findById(@PathVariable("id") final Long id, final UriComponentsBuilder uriBuilder, final HttpServletResponse response) { + return new Foo(randomAlphabetic(6)); + } + + // read - multiple + + @RequestMapping(method = RequestMethod.GET) + @ResponseBody + public List findAll() { + return Arrays.asList(new Foo(randomAlphabetic(6))); + } + + // write - just for test + @RequestMapping(method = RequestMethod.POST) + @ResponseStatus(HttpStatus.CREATED) + @ResponseBody + public Foo create(@RequestBody final Foo foo) { + return foo; + } +} \ No newline at end of file diff --git a/spring-security-mvc-custom/src/main/java/org/baeldung/web/dto/Foo.java b/spring-security-mvc-custom/src/main/java/org/baeldung/web/dto/Foo.java new file mode 100644 index 0000000000..02283e7df9 --- /dev/null +++ b/spring-security-mvc-custom/src/main/java/org/baeldung/web/dto/Foo.java @@ -0,0 +1,80 @@ +package org.baeldung.web.dto; + +import java.io.Serializable; + +public class Foo implements Serializable { + + private long id; + + private String name; + + public Foo() { + super(); + } + + public Foo(final String name) { + super(); + + this.name = name; + } + + // API + + public long getId() { + return id; + } + + public void setId(final long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + + // + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Foo other = (Foo) obj; + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + return true; + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("Foo [name=") + .append(name) + .append("]"); + return builder.toString(); + } + +} \ No newline at end of file diff --git a/spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/LoggerInterceptor.java b/spring-security-mvc-custom/src/main/java/org/baeldung/web/interceptor/LoggerInterceptor.java similarity index 100% rename from spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/LoggerInterceptor.java rename to spring-security-mvc-custom/src/main/java/org/baeldung/web/interceptor/LoggerInterceptor.java diff --git a/spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/SessionTimerInterceptor.java b/spring-security-mvc-custom/src/main/java/org/baeldung/web/interceptor/SessionTimerInterceptor.java similarity index 100% rename from spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/SessionTimerInterceptor.java rename to spring-security-mvc-custom/src/main/java/org/baeldung/web/interceptor/SessionTimerInterceptor.java diff --git a/spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/UserInterceptor.java b/spring-security-mvc-custom/src/main/java/org/baeldung/web/interceptor/UserInterceptor.java similarity index 100% rename from spring-security-rest-full/src/main/java/org/baeldung/web/interceptor/UserInterceptor.java rename to spring-security-mvc-custom/src/main/java/org/baeldung/web/interceptor/UserInterceptor.java diff --git a/spring-security-mvc-custom/src/main/resources/webSecurityConfig.xml b/spring-security-mvc-custom/src/main/resources/webSecurityConfig.xml index f31f36655c..f2ecaba5c8 100644 --- a/spring-security-mvc-custom/src/main/resources/webSecurityConfig.xml +++ b/spring-security-mvc-custom/src/main/resources/webSecurityConfig.xml @@ -33,4 +33,8 @@ + + \ No newline at end of file diff --git a/spring-security-rest-full/src/main/webapp/WEB-INF/view/csrfHome.jsp b/spring-security-mvc-custom/src/main/webapp/WEB-INF/view/csrfHome.jsp similarity index 100% rename from spring-security-rest-full/src/main/webapp/WEB-INF/view/csrfHome.jsp rename to spring-security-mvc-custom/src/main/webapp/WEB-INF/view/csrfHome.jsp diff --git a/spring-security-rest-full/src/test/java/org/baeldung/security/csrf/CsrfAbstractIntegrationTest.java b/spring-security-mvc-custom/src/test/java/org/baeldung/security/csrf/CsrfAbstractIntegrationTest.java similarity index 93% rename from spring-security-rest-full/src/test/java/org/baeldung/security/csrf/CsrfAbstractIntegrationTest.java rename to spring-security-mvc-custom/src/test/java/org/baeldung/security/csrf/CsrfAbstractIntegrationTest.java index 6e70f979c8..44424bf7f9 100644 --- a/spring-security-rest-full/src/test/java/org/baeldung/security/csrf/CsrfAbstractIntegrationTest.java +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/security/csrf/CsrfAbstractIntegrationTest.java @@ -5,7 +5,7 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock import javax.servlet.Filter; -import org.baeldung.persistence.model.Foo; +import org.baeldung.web.dto.Foo; import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -14,15 +14,15 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.RequestPostProcessor; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.WebApplicationContext; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; + + @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration -@Transactional public abstract class CsrfAbstractIntegrationTest { @Autowired diff --git a/spring-security-mvc-custom/src/test/java/org/baeldung/security/csrf/CsrfDisabledIntegrationTest.java b/spring-security-mvc-custom/src/test/java/org/baeldung/security/csrf/CsrfDisabledIntegrationTest.java new file mode 100644 index 0000000000..1d16e08514 --- /dev/null +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/security/csrf/CsrfDisabledIntegrationTest.java @@ -0,0 +1,25 @@ +package org.baeldung.security.csrf; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.baeldung.security.spring.SecurityWithoutCsrfConfig; +import org.baeldung.spring.MvcConfig; +import org.junit.Test; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; + +@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class }) +public class CsrfDisabledIntegrationTest extends CsrfAbstractIntegrationTest { + + @Test + public void givenNotAuth_whenAddFoo_thenUnauthorized() throws Exception { + mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo())).andExpect(status().isUnauthorized()); + } + + @Test + public void givenAuth_whenAddFoo_thenCreated() throws Exception { + mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo()).with(testUser())).andExpect(status().isCreated()); + } + +} diff --git a/spring-security-rest-full/src/test/java/org/baeldung/security/csrf/CsrfEnabledIntegrationTest.java b/spring-security-mvc-custom/src/test/java/org/baeldung/security/csrf/CsrfEnabledIntegrationTest.java similarity index 90% rename from spring-security-rest-full/src/test/java/org/baeldung/security/csrf/CsrfEnabledIntegrationTest.java rename to spring-security-mvc-custom/src/test/java/org/baeldung/security/csrf/CsrfEnabledIntegrationTest.java index 939b745de8..9d882973bd 100644 --- a/spring-security-rest-full/src/test/java/org/baeldung/security/csrf/CsrfEnabledIntegrationTest.java +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/security/csrf/CsrfEnabledIntegrationTest.java @@ -5,13 +5,12 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.baeldung.security.spring.SecurityWithCsrfConfig; -import org.baeldung.spring.PersistenceConfig; -import org.baeldung.spring.WebConfig; +import org.baeldung.spring.MvcConfig; import org.junit.Test; import org.springframework.http.MediaType; import org.springframework.test.context.ContextConfiguration; -@ContextConfiguration(classes = { SecurityWithCsrfConfig.class, PersistenceConfig.class, WebConfig.class }) +@ContextConfiguration(classes = { SecurityWithCsrfConfig.class, MvcConfig.class }) public class CsrfEnabledIntegrationTest extends CsrfAbstractIntegrationTest { @Test diff --git a/spring-security-rest-full/src/test/java/org/baeldung/security/spring/SecurityWithCsrfConfig.java b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithCsrfConfig.java similarity index 82% rename from spring-security-rest-full/src/test/java/org/baeldung/security/spring/SecurityWithCsrfConfig.java rename to spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithCsrfConfig.java index 97ae1f1dd2..9600977e37 100644 --- a/spring-security-rest-full/src/test/java/org/baeldung/security/spring/SecurityWithCsrfConfig.java +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithCsrfConfig.java @@ -1,8 +1,5 @@ package org.baeldung.security.spring; -import org.baeldung.web.error.CustomAccessDeniedHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; @@ -12,14 +9,10 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration -@EnableAutoConfiguration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter { - @Autowired - private CustomAccessDeniedHandler accessDeniedHandler; - public SecurityWithCsrfConfig() { super(); } @@ -46,8 +39,6 @@ public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter { .and() .httpBasic() .and() - .exceptionHandling().accessDeniedHandler(accessDeniedHandler) - .and() .headers().cacheControl().disable() ; // @formatter:on diff --git a/spring-security-rest-full/src/main/java/org/baeldung/security/spring/SecurityWithoutCsrfConfig.java b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithoutCsrfConfig.java similarity index 72% rename from spring-security-rest-full/src/main/java/org/baeldung/security/spring/SecurityWithoutCsrfConfig.java rename to spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithoutCsrfConfig.java index f1a78d1472..f7dbd5b42c 100644 --- a/spring-security-rest-full/src/main/java/org/baeldung/security/spring/SecurityWithoutCsrfConfig.java +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/security/spring/SecurityWithoutCsrfConfig.java @@ -1,8 +1,5 @@ package org.baeldung.security.spring; -import org.baeldung.web.error.CustomAccessDeniedHandler; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; @@ -12,16 +9,10 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration -@EnableAutoConfiguration -// @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) -// @ImportResource({ "classpath:webSecurityConfig.xml" }) public class SecurityWithoutCsrfConfig extends WebSecurityConfigurerAdapter { - @Autowired - private CustomAccessDeniedHandler accessDeniedHandler; - public SecurityWithoutCsrfConfig() { super(); } @@ -42,18 +33,15 @@ public class SecurityWithoutCsrfConfig extends WebSecurityConfigurerAdapter { protected void configure(final HttpSecurity http) throws Exception { // @formatter:off http - .csrf().disable() .authorizeRequests() - .antMatchers("/auth/admin/*").hasRole("ADMIN") - .antMatchers("/auth/*").hasAnyRole("ADMIN","USER") - .antMatchers("/*").permitAll() + .antMatchers("/auth/admin/*").hasAnyRole("ROLE_ADMIN") + .anyRequest().authenticated() .and() .httpBasic() .and() - // .exceptionHandling().accessDeniedPage("/my-error-page") - .exceptionHandling().accessDeniedHandler(accessDeniedHandler) - .and() .headers().cacheControl().disable() + .and() + .csrf().disable() ; // @formatter:on } diff --git a/spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/LoggerInterceptorIntegrationTest.java b/spring-security-mvc-custom/src/test/java/org/baeldung/web/interceptor/LoggerInterceptorIntegrationTest.java similarity index 83% rename from spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/LoggerInterceptorIntegrationTest.java rename to spring-security-mvc-custom/src/test/java/org/baeldung/web/interceptor/LoggerInterceptorIntegrationTest.java index 44dc860e62..c33c9a04e8 100644 --- a/spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/LoggerInterceptorIntegrationTest.java +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/web/interceptor/LoggerInterceptorIntegrationTest.java @@ -4,8 +4,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.baeldung.security.spring.SecurityWithoutCsrfConfig; -import org.baeldung.spring.PersistenceConfig; -import org.baeldung.spring.WebConfig; +import org.baeldung.spring.MvcConfig; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -16,13 +15,11 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration -@Transactional -@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, PersistenceConfig.class, WebConfig.class }) +@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class }) public class LoggerInterceptorIntegrationTest { @Autowired @@ -46,7 +43,8 @@ public class LoggerInterceptorIntegrationTest { */ @Test public void testInterceptors() throws Exception { - mockMvc.perform(get("/graph.html")).andExpect(status().isOk()); + mockMvc.perform(get("/login.html")) + .andExpect(status().isOk()); } } diff --git a/spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/SessionTimerInterceptorIntegrationTest.java b/spring-security-mvc-custom/src/test/java/org/baeldung/web/interceptor/SessionTimerInterceptorIntegrationTest.java similarity index 78% rename from spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/SessionTimerInterceptorIntegrationTest.java rename to spring-security-mvc-custom/src/test/java/org/baeldung/web/interceptor/SessionTimerInterceptorIntegrationTest.java index d62fab0670..bdc1be2c44 100644 --- a/spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/SessionTimerInterceptorIntegrationTest.java +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/web/interceptor/SessionTimerInterceptorIntegrationTest.java @@ -6,8 +6,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import javax.servlet.http.HttpSession; import org.baeldung.security.spring.SecurityWithoutCsrfConfig; -import org.baeldung.spring.PersistenceConfig; -import org.baeldung.spring.WebConfig; +import org.baeldung.spring.MvcConfig; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -20,13 +19,11 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration -@Transactional -@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, PersistenceConfig.class, WebConfig.class }) +@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class }) @WithMockUser(username = "admin", roles = { "USER", "ADMIN" }) public class SessionTimerInterceptorIntegrationTest { @@ -47,9 +44,14 @@ public class SessionTimerInterceptorIntegrationTest { */ @Test public void testInterceptors() throws Exception { - HttpSession session = mockMvc.perform(get("/auth/admin")).andExpect(status().is2xxSuccessful()).andReturn().getRequest().getSession(); + HttpSession session = mockMvc.perform(get("/auth/foos")) + .andExpect(status().is2xxSuccessful()) + .andReturn() + .getRequest() + .getSession(); Thread.sleep(51000); - mockMvc.perform(get("/auth/admin").session((MockHttpSession) session)).andExpect(status().is2xxSuccessful()); + mockMvc.perform(get("/auth/foos").session((MockHttpSession) session)) + .andExpect(status().is2xxSuccessful()); } } diff --git a/spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/UserInterceptorIntegrationTest.java b/spring-security-mvc-custom/src/test/java/org/baeldung/web/interceptor/UserInterceptorIntegrationTest.java similarity index 84% rename from spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/UserInterceptorIntegrationTest.java rename to spring-security-mvc-custom/src/test/java/org/baeldung/web/interceptor/UserInterceptorIntegrationTest.java index f995f86145..a85fd999a6 100644 --- a/spring-security-rest-full/src/test/java/org/baeldung/web/interceptor/UserInterceptorIntegrationTest.java +++ b/spring-security-mvc-custom/src/test/java/org/baeldung/web/interceptor/UserInterceptorIntegrationTest.java @@ -1,8 +1,10 @@ package org.baeldung.web.interceptor; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import org.baeldung.security.spring.SecurityWithoutCsrfConfig; -import org.baeldung.spring.PersistenceConfig; -import org.baeldung.spring.WebConfig; +import org.baeldung.spring.MvcConfig; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -14,16 +16,11 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.context.WebApplicationContext; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration -@Transactional -@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, PersistenceConfig.class, WebConfig.class }) +@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, MvcConfig.class }) @WithMockUser(username = "admin", roles = { "USER", "ADMIN" }) public class UserInterceptorIntegrationTest { @@ -46,7 +43,8 @@ public class UserInterceptorIntegrationTest { */ @Test public void testInterceptors() throws Exception { - mockMvc.perform(get("/auth/admin")).andExpect(status().is2xxSuccessful()); + mockMvc.perform(get("/auth/foos")) + .andExpect(status().is2xxSuccessful()); } } diff --git a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SecurityConfig.java b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SecurityConfig.java index 7006619d35..d7b57d1829 100644 --- a/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SecurityConfig.java +++ b/spring-security-mvc-socket/src/main/java/com/baeldung/springsecuredsockets/config/SecurityConfig.java @@ -88,8 +88,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .authorizeRequests() .antMatchers("/", "/index", "/authenticate") .permitAll() - .antMatchers("/secured/**/**", - "/secured/success", "/secured/socket", "/secured/success") + .antMatchers("/secured/**/**", "/secured/socket", "/secured/success") .authenticated() .anyRequest().authenticated() .and() diff --git a/spring-security-rest-basic-auth/README.md b/spring-security-rest-basic-auth/README.md index 43ab08b8ca..f92fcfe36b 100644 --- a/spring-security-rest-basic-auth/README.md +++ b/spring-security-rest-basic-auth/README.md @@ -6,8 +6,8 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ### Relevant Articles: -- [RestTemplate with Basic Authentication in Spring](http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1) +- [RestTemplate with Basic Authentication in Spring](http://www.baeldung.com/how-to-use-resttemplate-with-basic-authentication-in-spring) - [HttpClient Timeout](http://www.baeldung.com/httpclient-timeout) - [HttpClient with SSL](http://www.baeldung.com/httpclient-ssl) - [Writing a Custom Filter in Spring Security](http://www.baeldung.com/spring-security-custom-filter) -- [Spring Security Basic Authentication](http://www.baeldung.com/spring-security-basic-authentication) \ No newline at end of file +- [Spring Security Basic Authentication](http://www.baeldung.com/spring-security-basic-authentication) diff --git a/spring-security-rest-full/.springBeans b/spring-security-rest-full/.springBeans deleted file mode 100644 index f100c6afbe..0000000000 --- a/spring-security-rest-full/.springBeans +++ /dev/null @@ -1,19 +0,0 @@ - - - 1 - - - - - - - java:org.baeldung.security.spring.SecurityWithoutCsrfConfig - - - src/main/webapp/WEB-INF/api-servlet.xml - java:org.baeldung.spring.Application - java:org.baeldung.security.spring.SecurityWithCsrfConfig - - - - diff --git a/spring-security-rest-full/README.md b/spring-security-rest-full/README.md deleted file mode 100644 index d5bd8be52b..0000000000 --- a/spring-security-rest-full/README.md +++ /dev/null @@ -1,57 +0,0 @@ -========= - -## REST Example Project with Spring Security - -### Courses -The "REST With Spring" Classes: http://bit.ly/restwithspring - -The "Learn Spring Security" Classes: http://github.learnspringsecurity.com - -### Relevant Articles: -- [Spring Security Expressions - hasRole Example](http://www.baeldung.com/spring-security-expressions-basic) -- [REST Pagination in Spring](http://www.baeldung.com/2012/01/18/rest-pagination-in-spring/) -- [HATEOAS for a Spring REST Service](http://www.baeldung.com/2011/11/13/rest-service-discoverability-with-spring-part-5/) -- [REST API Discoverability and HATEOAS](http://www.baeldung.com/2011/11/06/restful-web-service-discoverability-part-4/) -- [ETags for REST with Spring](http://www.baeldung.com/2013/01/11/etags-for-rest-with-spring/) -- [Error Handling for REST with Spring 3](http://www.baeldung.com/2013/01/31/exception-handling-for-rest-with-spring-3-2/) -- [Integration Testing with the Maven Cargo plugin](http://www.baeldung.com/2011/10/16/how-to-set-up-integration-testing-with-the-maven-cargo-plugin/) -- [Introduction to Spring Data JPA](http://www.baeldung.com/2011/12/22/the-persistence-layer-with-spring-data-jpa/) -- [Project Configuration with Spring](http://www.baeldung.com/2012/03/12/project-configuration-with-spring/) -- [REST Query Language with Spring and JPA Criteria](http://www.baeldung.com/rest-search-language-spring-jpa-criteria) -- [REST Query Language with Spring Data JPA Specifications](http://www.baeldung.com/rest-api-search-language-spring-data-specifications) -- [REST Query Language with Spring Data JPA and QueryDSL](http://www.baeldung.com/rest-api-search-language-spring-data-querydsl) -- [REST Query Language – Advanced Search Operations](http://www.baeldung.com/rest-api-query-search-language-more-operations) -- [Metrics for your Spring REST API](http://www.baeldung.com/spring-rest-api-metrics) -- [REST Query Language with RSQL](http://www.baeldung.com/rest-api-search-language-rsql-fiql) -- [Spring RestTemplate Tutorial](http://www.baeldung.com/rest-template) -- [A Guide to CSRF Protection in Spring Security](http://www.baeldung.com/spring-security-csrf) -- [Intro to Spring Security Expressions](http://www.baeldung.com/spring-security-expressions) -- [Changing Spring Model Parameters with Handler Interceptor](http://www.baeldung.com/spring-model-parameters-with-handler-interceptor) -- [Introduction to Spring MVC HandlerInterceptor](http://www.baeldung.com/spring-mvc-handlerinterceptor) -- [Using a Custom Spring MVC’s Handler Interceptor to Manage Sessions](http://www.baeldung.com/spring-mvc-custom-handler-interceptor) -- [Bootstrap a Web Application with Spring 4](http://www.baeldung.com/bootstraping-a-web-application-with-spring-and-java-based-configuration) -- [REST Query Language – Implementing OR Operation](http://www.baeldung.com/rest-api-query-search-or-operation) - - - - -### Build the Project -``` -mvn clean install -``` - - -### Set up MySQL -``` -mysql -u root -p -> CREATE USER 'tutorialuser'@'localhost' IDENTIFIED BY 'tutorialmy5ql'; -> GRANT ALL PRIVILEGES ON *.* TO 'tutorialuser'@'localhost'; -> FLUSH PRIVILEGES; -``` - - -### Use the REST Service - -``` -curl http://localhost:8080/spring-security-rest-full/foos -``` diff --git a/spring-security-rest-full/src/main/resources/application.properties b/spring-security-rest-full/src/main/resources/application.properties deleted file mode 100644 index c3e1f0b4bb..0000000000 --- a/spring-security-rest-full/src/main/resources/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -server.port=8082 -server.context-path=/spring-security-rest-full -endpoints.metrics.enabled=true \ No newline at end of file diff --git a/spring-security-rest-full/src/main/resources/webSecurityConfig.xml b/spring-security-rest-full/src/main/resources/webSecurityConfig.xml deleted file mode 100644 index be6b4d0c27..0000000000 --- a/spring-security-rest-full/src/main/resources/webSecurityConfig.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-security-rest-full/src/test/java/org/baeldung/persistence/PersistenceTestSuite.java b/spring-security-rest-full/src/test/java/org/baeldung/persistence/PersistenceTestSuite.java deleted file mode 100644 index fda7b01c7a..0000000000 --- a/spring-security-rest-full/src/test/java/org/baeldung/persistence/PersistenceTestSuite.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.baeldung.persistence; - -import org.baeldung.persistence.query.JPACriteriaQueryIntegrationTest; -import org.baeldung.persistence.query.JPAQuerydslIntegrationTest; -import org.baeldung.persistence.query.JPASpecificationIntegrationTest; -import org.baeldung.persistence.query.RsqlIntegrationTest; -import org.baeldung.persistence.service.FooServicePersistenceIntegrationTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -@RunWith(Suite.class) -@Suite.SuiteClasses({ - // @formatter:off - RsqlIntegrationTest.class - ,JPASpecificationIntegrationTest.class - ,FooServicePersistenceIntegrationTest.class - ,JPAQuerydslIntegrationTest.class - ,JPACriteriaQueryIntegrationTest.class -}) // -public class PersistenceTestSuite { - -} diff --git a/spring-security-rest-full/src/test/java/org/baeldung/security/SecurityTestSuite.java b/spring-security-rest-full/src/test/java/org/baeldung/security/SecurityTestSuite.java deleted file mode 100644 index 8b754a03ff..0000000000 --- a/spring-security-rest-full/src/test/java/org/baeldung/security/SecurityTestSuite.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.security; - -import org.baeldung.security.csrf.CsrfDisabledIntegrationTest; -import org.baeldung.security.csrf.CsrfEnabledIntegrationTest; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - -@RunWith(Suite.class) -@Suite.SuiteClasses({ - // @formatter:off - CsrfEnabledIntegrationTest.class - ,CsrfDisabledIntegrationTest.class -}) // -public class SecurityTestSuite { - -} diff --git a/spring-security-rest-full/src/test/java/org/baeldung/security/csrf/CsrfDisabledIntegrationTest.java b/spring-security-rest-full/src/test/java/org/baeldung/security/csrf/CsrfDisabledIntegrationTest.java deleted file mode 100644 index e06461fc2c..0000000000 --- a/spring-security-rest-full/src/test/java/org/baeldung/security/csrf/CsrfDisabledIntegrationTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.baeldung.security.csrf; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import org.baeldung.security.spring.SecurityWithoutCsrfConfig; -import org.baeldung.spring.PersistenceConfig; -import org.baeldung.spring.WebConfig; -import org.junit.Test; -import org.springframework.http.MediaType; -import org.springframework.test.context.ContextConfiguration; - -@ContextConfiguration(classes = { SecurityWithoutCsrfConfig.class, PersistenceConfig.class, WebConfig.class }) -public class CsrfDisabledIntegrationTest extends CsrfAbstractIntegrationTest { - - @Test - public void givenNotAuth_whenAddFoo_thenUnauthorized() throws Exception { - mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo())).andExpect(status().isUnauthorized()); - } - - @Test - public void givenAuth_whenAddFoo_thenCreated() throws Exception { - mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo()).with(testUser())).andExpect(status().isCreated()); - } - - @Test - public void accessMainPageWithoutAuthorization() throws Exception { - mvc.perform(get("/graph.html").contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); - } - - @Test - public void accessOtherPages() throws Exception { - mvc.perform(get("/auth/transfer").contentType(MediaType.APPLICATION_JSON).param("accountNo", "1").param("amount", "100")).andExpect(status().isUnauthorized()); // without authorization - mvc.perform(get("/auth/transfer").contentType(MediaType.APPLICATION_JSON).param("accountNo", "1").param("amount", "100").with(testUser())).andExpect(status().isOk()); // with authorization - } - - @Test - public void accessAdminPage() throws Exception { - mvc.perform(get("/auth/admin/x").contentType(MediaType.APPLICATION_JSON)).andExpect(status().isUnauthorized()); // without authorization - mvc.perform(get("/auth/admin/x").contentType(MediaType.APPLICATION_JSON).with(testAdmin())).andExpect(status().isOk()); // with authorization - } - -} diff --git a/spring-security-rest/README.md b/spring-security-rest/README.md index 92b759a66a..5898ba248e 100644 --- a/spring-security-rest/README.md +++ b/spring-security-rest/README.md @@ -14,3 +14,6 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com - [An Intro to Spring HATEOAS](http://www.baeldung.com/spring-hateoas-tutorial) - [Spring Security Context Propagation with @Async](http://www.baeldung.com/spring-security-async-principal-propagation) - [Servlet 3 Async Support with Spring MVC and Spring Security](http://www.baeldung.com/spring-mvc-async-security) +- [Intro to Spring Security Expressions](http://www.baeldung.com/spring-security-expressions) +- [Spring Security Expressions - hasRole Example](http://www.baeldung.com/spring-security-expressions-basic) +- [Error Handling for REST with Spring 3](http://www.baeldung.com/2013/01/31/exception-handling-for-rest-with-spring-3-2/) diff --git a/spring-security-rest/pom.xml b/spring-security-rest/pom.xml index 13db431ae3..e4bb071a6a 100644 --- a/spring-security-rest/pom.xml +++ b/spring-security-rest/pom.xml @@ -28,7 +28,7 @@ spring-security-config ${org.springframework.security.version} - + diff --git a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java index 2dbc9b8f08..c3e738297a 100644 --- a/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java +++ b/spring-security-rest/src/main/java/org/baeldung/spring/SecurityJavaConfig.java @@ -1,10 +1,13 @@ package org.baeldung.spring; import org.baeldung.security.MySavedRequestAwareAuthenticationSuccessHandler; +import org.baeldung.web.error.CustomAccessDeniedHandler; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -13,9 +16,13 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa @Configuration @EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) @ComponentScan("org.baeldung.security") public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { + @Autowired + private CustomAccessDeniedHandler accessDeniedHandler; + // @Autowired // private RestAuthenticationEntryPoint restAuthenticationEntryPoint; @@ -40,14 +47,15 @@ public class SecurityJavaConfig extends WebSecurityConfigurerAdapter { .csrf().disable() .authorizeRequests() .and() - .exceptionHandling() -// .authenticationEntryPoint(restAuthenticationEntryPoint) + .exceptionHandling().accessDeniedHandler(accessDeniedHandler) + // .authenticationEntryPoint(restAuthenticationEntryPoint) .and() .authorizeRequests() .antMatchers("/api/csrfAttacker*").permitAll() .antMatchers("/api/customer/**").permitAll() .antMatchers("/api/foos/**").authenticated() .antMatchers("/api/async/**").permitAll() + .antMatchers("/api/admin/**").hasRole("ADMIN") .and() .httpBasic() // .and() diff --git a/spring-security-rest/src/main/java/org/baeldung/spring/SwaggerConfig.java b/spring-security-rest/src/main/java/org/baeldung/spring/SwaggerConfig.java index 00ccb36666..bcf6657eee 100644 --- a/spring-security-rest/src/main/java/org/baeldung/spring/SwaggerConfig.java +++ b/spring-security-rest/src/main/java/org/baeldung/spring/SwaggerConfig.java @@ -1,19 +1,23 @@ package org.baeldung.spring; +import static com.google.common.collect.Lists.newArrayList; + +import java.util.Collections; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.RequestMethod; + import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.builders.ResponseMessageBuilder; import springfox.documentation.schema.ModelRef; import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; -import static com.google.common.collect.Lists.newArrayList; - @Configuration @EnableSwagger2 public class SwaggerConfig { @@ -25,7 +29,7 @@ public class SwaggerConfig { } private ApiInfo apiInfo() { - ApiInfo apiInfo = new ApiInfo("My REST API", "Some custom description of API.", "API TOS", "Terms of service", "myeaddress@company.com", "License of API", "API license URL"); + ApiInfo apiInfo = new ApiInfo("My REST API", "Some custom description of API.", "API TOS", "Terms of service", new Contact("John Doe", "www.example.com", "myeaddress@company.com"), "License of API", "API license URL", Collections.emptyList()); return apiInfo; } } diff --git a/spring-security-rest/src/main/java/org/baeldung/web/controller/RootController.java b/spring-security-rest/src/main/java/org/baeldung/web/controller/RootController.java new file mode 100644 index 0000000000..4253ed7a59 --- /dev/null +++ b/spring-security-rest/src/main/java/org/baeldung/web/controller/RootController.java @@ -0,0 +1,30 @@ +package org.baeldung.web.controller; + +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.ResponseBody; + +@Controller +public class RootController { + + public RootController() { + super(); + } + + // API + + @RequestMapping(value = "/admin/x", method = RequestMethod.GET) + @ResponseBody + public String sampleAdminPage() { + return "Hello"; + } + + + @RequestMapping(value = "/my-error-page", method = RequestMethod.GET) + @ResponseBody + public String sampleErrorPage() { + return "Error Occurred"; + } + +} diff --git a/spring-security-rest-full/src/main/java/org/baeldung/web/error/CustomAccessDeniedHandler.java b/spring-security-rest/src/main/java/org/baeldung/web/error/CustomAccessDeniedHandler.java similarity index 100% rename from spring-security-rest-full/src/main/java/org/baeldung/web/error/CustomAccessDeniedHandler.java rename to spring-security-rest/src/main/java/org/baeldung/web/error/CustomAccessDeniedHandler.java diff --git a/spring-security-rest/src/main/java/org/baeldung/web/error/RestResponseEntityExceptionHandler.java b/spring-security-rest/src/main/java/org/baeldung/web/error/RestResponseEntityExceptionHandler.java new file mode 100644 index 0000000000..9ff4f040fe --- /dev/null +++ b/spring-security-rest/src/main/java/org/baeldung/web/error/RestResponseEntityExceptionHandler.java @@ -0,0 +1,74 @@ +package org.baeldung.web.error; + +import org.springframework.dao.DataAccessException; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; +//import org.springframework.security.access.AccessDeniedException; + +@ControllerAdvice +public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler { + + public RestResponseEntityExceptionHandler() { + super(); + } + + // API + + // 400 + + @ExceptionHandler({ DataIntegrityViolationException.class }) + public ResponseEntity handleBadRequest(final DataIntegrityViolationException ex, final WebRequest request) { + final String bodyOfResponse = "This should be application specific"; + return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.BAD_REQUEST, request); + } + + @Override + protected ResponseEntity handleHttpMessageNotReadable(final HttpMessageNotReadableException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { + final String bodyOfResponse = "This should be application specific"; + // ex.getCause() instanceof JsonMappingException, JsonParseException // for additional information later on + return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request); + } + + @Override + protected ResponseEntity handleMethodArgumentNotValid(final MethodArgumentNotValidException ex, final HttpHeaders headers, final HttpStatus status, final WebRequest request) { + final String bodyOfResponse = "This should be application specific"; + return handleExceptionInternal(ex, bodyOfResponse, headers, HttpStatus.BAD_REQUEST, request); + } + + // 403 + @ExceptionHandler({ AccessDeniedException.class }) + public ResponseEntity handleAccessDeniedException(final Exception ex, final WebRequest request) { + System.out.println("request" + request.getUserPrincipal()); + return new ResponseEntity("Access denied message here", new HttpHeaders(), HttpStatus.FORBIDDEN); + } + + // 409 + + @ExceptionHandler({ InvalidDataAccessApiUsageException.class, DataAccessException.class }) + protected ResponseEntity handleConflict(final RuntimeException ex, final WebRequest request) { + final String bodyOfResponse = "This should be application specific"; + return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.CONFLICT, request); + } + + // 412 + + // 500 + + @ExceptionHandler({ NullPointerException.class, IllegalArgumentException.class, IllegalStateException.class }) + /*500*/public ResponseEntity handleInternal(final RuntimeException ex, final WebRequest request) { + logger.error("500 Status Code", ex); + final String bodyOfResponse = "This should be application specific"; + return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request); + } + +} diff --git a/spring-security-rest/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java b/spring-security-rest/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java new file mode 100644 index 0000000000..14b61f9832 --- /dev/null +++ b/spring-security-rest/src/main/java/org/baeldung/web/exception/MyResourceNotFoundException.java @@ -0,0 +1,21 @@ +package org.baeldung.web.exception; + +public final class MyResourceNotFoundException extends RuntimeException { + + public MyResourceNotFoundException() { + super(); + } + + public MyResourceNotFoundException(final String message, final Throwable cause) { + super(message, cause); + } + + public MyResourceNotFoundException(final String message) { + super(message); + } + + public MyResourceNotFoundException(final Throwable cause) { + super(cause); + } + +} diff --git a/spring-security-rest/src/main/resources/webSecurityConfig.xml b/spring-security-rest/src/main/resources/webSecurityConfig.xml index a260460d76..4bb208a195 100644 --- a/spring-security-rest/src/main/resources/webSecurityConfig.xml +++ b/spring-security-rest/src/main/resources/webSecurityConfig.xml @@ -10,6 +10,8 @@ http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> + + @@ -17,6 +19,11 @@ + + + + + @@ -30,8 +37,12 @@ + + + + \ No newline at end of file diff --git a/spring-security-rest/src/test/java/org/baeldung/web/FooLiveTest.java b/spring-security-rest/src/test/java/org/baeldung/web/FooLiveTest.java index 0ef50f745a..0a53da674a 100644 --- a/spring-security-rest/src/test/java/org/baeldung/web/FooLiveTest.java +++ b/spring-security-rest/src/test/java/org/baeldung/web/FooLiveTest.java @@ -17,17 +17,20 @@ import com.jayway.restassured.specification.RequestSpecification; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigContextLoader.class) public class FooLiveTest { - private static final String URL_PREFIX = "http://localhost:8082/spring-security-rest"; + private static final String URL_PREFIX = "http://localhost:8080/spring-security-rest"; // private FormAuthConfig formConfig = new FormAuthConfig(URL_PREFIX + "/login", "temporary", "temporary"); private String cookie; private RequestSpecification givenAuth() { // return RestAssured.given().auth().form("user", "userPass", formConfig); - if (cookie == null) { - cookie = RestAssured.given().contentType("application/x-www-form-urlencoded").formParam("password", "userPass").formParam("username", "user").post(URL_PREFIX + "/login").getCookie("JSESSIONID"); - } - return RestAssured.given().cookie("JSESSIONID", cookie); + // if (cookie == null) { + // cookie = RestAssured.given().contentType("application/x-www-form-urlencoded").formParam("password", "userPass").formParam("username", "user").post(URL_PREFIX + "/login").getCookie("JSESSIONID"); + // } + // return RestAssured.given().cookie("JSESSIONID", cookie); + return RestAssured.given() + .auth() + .basic("user", "userPass"); } @Test diff --git a/spring-security-rest/src/test/java/org/baeldung/web/SwaggerLiveTest.java b/spring-security-rest/src/test/java/org/baeldung/web/SwaggerLiveTest.java index cf1516f8e1..792b3e28ce 100644 --- a/spring-security-rest/src/test/java/org/baeldung/web/SwaggerLiveTest.java +++ b/spring-security-rest/src/test/java/org/baeldung/web/SwaggerLiveTest.java @@ -8,7 +8,7 @@ import com.jayway.restassured.RestAssured; import com.jayway.restassured.response.Response; public class SwaggerLiveTest { - private static final String URL_PREFIX = "http://localhost:8082/spring-security-rest/api"; + private static final String URL_PREFIX = "http://localhost:8080/spring-security-rest/api"; @Test public void whenVerifySpringFoxIsWorking_thenOK() { diff --git a/spring-swagger-codegen/README.md b/spring-swagger-codegen/README.md new file mode 100644 index 0000000000..ee6b240c30 --- /dev/null +++ b/spring-swagger-codegen/README.md @@ -0,0 +1,3 @@ +### Relevant articles + +- [Generate Spring Boot REST Client with Swagger](http://www.baeldung.com/spring-boot-rest-client-swagger-codegen) diff --git a/spring-vertx/pom.xml b/spring-vertx/pom.xml index 2ab506f667..2b26d939a5 100644 --- a/spring-vertx/pom.xml +++ b/spring-vertx/pom.xml @@ -80,7 +80,7 @@ **/JdbcTest.java **/*LiveTest.java - true + diff --git a/struts2/README.md b/struts-2/README.md similarity index 100% rename from struts2/README.md rename to struts-2/README.md diff --git a/struts2/WebContent/WEB-INF/web.xml b/struts-2/WebContent/WEB-INF/web.xml similarity index 100% rename from struts2/WebContent/WEB-INF/web.xml rename to struts-2/WebContent/WEB-INF/web.xml diff --git a/struts2/WebContent/input.jsp b/struts-2/WebContent/input.jsp similarity index 100% rename from struts2/WebContent/input.jsp rename to struts-2/WebContent/input.jsp diff --git a/struts2/WebContent/result.jsp b/struts-2/WebContent/result.jsp similarity index 100% rename from struts2/WebContent/result.jsp rename to struts-2/WebContent/result.jsp diff --git a/struts2/pom.xml b/struts-2/pom.xml similarity index 100% rename from struts2/pom.xml rename to struts-2/pom.xml diff --git a/struts2/src/main/java/com/baeldung/struts/CarAction.java b/struts-2/src/main/java/com/baeldung/struts/CarAction.java similarity index 100% rename from struts2/src/main/java/com/baeldung/struts/CarAction.java rename to struts-2/src/main/java/com/baeldung/struts/CarAction.java diff --git a/struts2/src/main/java/com/baeldung/struts/CarMessageService.java b/struts-2/src/main/java/com/baeldung/struts/CarMessageService.java similarity index 100% rename from struts2/src/main/java/com/baeldung/struts/CarMessageService.java rename to struts-2/src/main/java/com/baeldung/struts/CarMessageService.java diff --git a/struts2/src/test/java/com/baeldung/struts/test/CarActionTest.java b/struts-2/src/test/java/com/baeldung/struts/test/CarActionTest.java similarity index 100% rename from struts2/src/test/java/com/baeldung/struts/test/CarActionTest.java rename to struts-2/src/test/java/com/baeldung/struts/test/CarActionTest.java diff --git a/testing-modules/README.md b/testing-modules/README.md new file mode 100644 index 0000000000..3fbeea6188 --- /dev/null +++ b/testing-modules/README.md @@ -0,0 +1,3 @@ + +## Testing Modules + diff --git a/gatling/README.md b/testing-modules/gatling/README.md similarity index 100% rename from gatling/README.md rename to testing-modules/gatling/README.md diff --git a/gatling/pom.xml b/testing-modules/gatling/pom.xml similarity index 100% rename from gatling/pom.xml rename to testing-modules/gatling/pom.xml diff --git a/gatling/src/test/resources/gatling.conf b/testing-modules/gatling/src/test/resources/gatling.conf similarity index 100% rename from gatling/src/test/resources/gatling.conf rename to testing-modules/gatling/src/test/resources/gatling.conf diff --git a/gatling/src/test/resources/logback.xml b/testing-modules/gatling/src/test/resources/logback.xml similarity index 100% rename from gatling/src/test/resources/logback.xml rename to testing-modules/gatling/src/test/resources/logback.xml diff --git a/gatling/src/test/resources/recorder.conf b/testing-modules/gatling/src/test/resources/recorder.conf similarity index 100% rename from gatling/src/test/resources/recorder.conf rename to testing-modules/gatling/src/test/resources/recorder.conf diff --git a/gatling/src/test/scala/Engine.scala b/testing-modules/gatling/src/test/scala/Engine.scala similarity index 100% rename from gatling/src/test/scala/Engine.scala rename to testing-modules/gatling/src/test/scala/Engine.scala diff --git a/gatling/src/test/scala/IDEPathHelper.scala b/testing-modules/gatling/src/test/scala/IDEPathHelper.scala similarity index 100% rename from gatling/src/test/scala/IDEPathHelper.scala rename to testing-modules/gatling/src/test/scala/IDEPathHelper.scala diff --git a/gatling/src/test/scala/Recorder.scala b/testing-modules/gatling/src/test/scala/Recorder.scala similarity index 100% rename from gatling/src/test/scala/Recorder.scala rename to testing-modules/gatling/src/test/scala/Recorder.scala diff --git a/gatling/src/test/scala/org/baeldung/RecordedSimulation.scala b/testing-modules/gatling/src/test/scala/org/baeldung/RecordedSimulation.scala similarity index 100% rename from gatling/src/test/scala/org/baeldung/RecordedSimulation.scala rename to testing-modules/gatling/src/test/scala/org/baeldung/RecordedSimulation.scala diff --git a/groovy-spock/README.md b/testing-modules/groovy-spock/README.md similarity index 100% rename from groovy-spock/README.md rename to testing-modules/groovy-spock/README.md diff --git a/groovy-spock/pom.xml b/testing-modules/groovy-spock/pom.xml similarity index 97% rename from groovy-spock/pom.xml rename to testing-modules/groovy-spock/pom.xml index d9b51c5e1a..3d67657224 100644 --- a/groovy-spock/pom.xml +++ b/testing-modules/groovy-spock/pom.xml @@ -17,6 +17,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/groovy-spock/src/test/groovy/FirstSpecification.groovy b/testing-modules/groovy-spock/src/test/groovy/FirstSpecification.groovy similarity index 100% rename from groovy-spock/src/test/groovy/FirstSpecification.groovy rename to testing-modules/groovy-spock/src/test/groovy/FirstSpecification.groovy diff --git a/groovy-spock/src/test/groovy/Notifier.groovy b/testing-modules/groovy-spock/src/test/groovy/Notifier.groovy similarity index 100% rename from groovy-spock/src/test/groovy/Notifier.groovy rename to testing-modules/groovy-spock/src/test/groovy/Notifier.groovy diff --git a/groovy-spock/src/test/groovy/PaymentGateway.groovy b/testing-modules/groovy-spock/src/test/groovy/PaymentGateway.groovy similarity index 100% rename from groovy-spock/src/test/groovy/PaymentGateway.groovy rename to testing-modules/groovy-spock/src/test/groovy/PaymentGateway.groovy diff --git a/junit5/README.md b/testing-modules/junit-5/README.md similarity index 65% rename from junit5/README.md rename to testing-modules/junit-5/README.md index 49cd8e61a4..20ecb1eeab 100644 --- a/junit5/README.md +++ b/testing-modules/junit-5/README.md @@ -5,3 +5,6 @@ - [A Guide to @RepeatedTest in Junit 5](http://www.baeldung.com/junit-5-repeated-test) - [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests) - [A Guied to JUnit 5 Extensions](http://www.baeldung.com/junit-5-extensions) +- [Inject Parameters into JUnit Jupiter Unit Tests](http://www.baeldung.com/junit-5-parameters) +- [Mockito and JUnit 5 – Using ExtendWith](http://www.baeldung.com/mockito-junit-5-extension) +- [JUnit 5 – @RunWith](http://www.baeldung.com/junit-5-runwith) diff --git a/junit5/pom.xml b/testing-modules/junit-5/pom.xml similarity index 82% rename from junit5/pom.xml rename to testing-modules/junit-5/pom.xml index 1fa4818447..684a9253d5 100644 --- a/junit5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -4,30 +4,33 @@ 4.0.0 - junit5 + junit-5 1.0-SNAPSHOT - junit5 + junit-5 Intro to JUnit 5 com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ UTF-8 1.8 - 5.0.0-RC2 - 1.0.0-RC2 - 4.12.0-RC2 + 5.0.2 + 1.0.1 + 4.12.1 2.8.2 1.4.196 + 2.11.0 3.6.0 2.19.1 4.12 + 5.0.1.RELEASE @@ -110,7 +113,18 @@ ${junit4.version} test + + org.springframework + spring-test + ${spring.version} + test + + + org.springframework + spring-context + ${spring.version} + - \ No newline at end of file + diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/Greetings.java b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/Greetings.java new file mode 100644 index 0000000000..f43269f646 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/Greetings.java @@ -0,0 +1,9 @@ +package com.baeldung.junit5; + +public class Greetings { + + public static String sayHello() { + return "Hello"; + } + +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/User.java b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/User.java new file mode 100644 index 0000000000..4276fd62b9 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/User.java @@ -0,0 +1,41 @@ +package com.baeldung.junit5.mockito; + +public class User { + + private Integer id; + private String name; + private int age; + + public User() { + } + + public User(String name, int age) { + this.name = name; + this.age = age; + } + + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public int getAge() { + return age; + } + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return "User [id=" + id + ", name=" + name + ", age=" + age + "]"; + } + +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/repository/MailClient.java b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/repository/MailClient.java new file mode 100644 index 0000000000..d10169ef7a --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/repository/MailClient.java @@ -0,0 +1,9 @@ +package com.baeldung.junit5.mockito.repository; + +import com.baeldung.junit5.mockito.User; + +public interface MailClient { + + void sendUserRegistrationMail(User user); + +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/repository/SettingRepository.java b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/repository/SettingRepository.java new file mode 100644 index 0000000000..23ae8fa35c --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/repository/SettingRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.junit5.mockito.repository; + +public interface SettingRepository { + + int getUserMinAge(); + + int getUserNameMinLength(); + +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/repository/UserRepository.java b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/repository/UserRepository.java new file mode 100644 index 0000000000..e1b84c774b --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/repository/UserRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.junit5.mockito.repository; + +import com.baeldung.junit5.mockito.User; + +public interface UserRepository { + + User insert(User user); + boolean isUsernameAlreadyExists(String userName); + +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/service/DefaultUserService.java b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/service/DefaultUserService.java new file mode 100644 index 0000000000..888edbd710 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/service/DefaultUserService.java @@ -0,0 +1,46 @@ +package com.baeldung.junit5.mockito.service; + +import com.baeldung.junit5.mockito.User; +import com.baeldung.junit5.mockito.repository.MailClient; +import com.baeldung.junit5.mockito.repository.SettingRepository; +import com.baeldung.junit5.mockito.repository.UserRepository; + +public class DefaultUserService implements UserService { + + private UserRepository userRepository; + private SettingRepository settingRepository; + private MailClient mailClient; + + public DefaultUserService(UserRepository userRepository, SettingRepository settingRepository, MailClient mailClient) { + this.userRepository = userRepository; + this.settingRepository = settingRepository; + this.mailClient = mailClient; + } + + @Override + public User register(User user) { + validate(user); + User insertedUser = userRepository.insert(user); + mailClient.sendUserRegistrationMail(insertedUser); + return insertedUser; + } + + private void validate(User user) { + if(user.getName() == null) { + throw new RuntimeException(Errors.USER_NAME_REQUIRED); + } + + if(user.getName().length() < settingRepository.getUserNameMinLength()) { + throw new RuntimeException(Errors.USER_NAME_SHORT); + } + + if(user.getAge() < settingRepository.getUserMinAge()) { + throw new RuntimeException(Errors.USER_AGE_YOUNG); + } + + if(userRepository.isUsernameAlreadyExists(user.getName())) { + throw new RuntimeException(Errors.USER_NAME_DUPLICATE); + } + } + +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/service/Errors.java b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/service/Errors.java new file mode 100644 index 0000000000..28283754a3 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/service/Errors.java @@ -0,0 +1,10 @@ +package com.baeldung.junit5.mockito.service; + +public class Errors { + + public static final String USER_NAME_REQUIRED = "user.name.required"; + public static final String USER_NAME_SHORT = "user.name.short"; + public static final String USER_AGE_YOUNG = "user.age.young"; + public static final String USER_NAME_DUPLICATE = "user.name.duplicate"; + +} diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/service/UserService.java b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/service/UserService.java new file mode 100644 index 0000000000..326d019b4a --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/mockito/service/UserService.java @@ -0,0 +1,9 @@ +package com.baeldung.junit5.mockito.service; + +import com.baeldung.junit5.mockito.User; + +public interface UserService { + + User register(User user); + +} diff --git a/junit5/src/test/java/com/baeldung/AssertionUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/AssertionUnitTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/AssertionUnitTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/AssertionUnitTest.java diff --git a/junit5/src/test/java/com/baeldung/AssumptionUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/AssumptionUnitTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/AssumptionUnitTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/AssumptionUnitTest.java diff --git a/junit5/src/test/java/com/baeldung/DynamicTestsExample.java b/testing-modules/junit-5/src/test/java/com/baeldung/DynamicTestsExample.java similarity index 100% rename from junit5/src/test/java/com/baeldung/DynamicTestsExample.java rename to testing-modules/junit-5/src/test/java/com/baeldung/DynamicTestsExample.java diff --git a/junit5/src/test/java/com/baeldung/EmployeesTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/EmployeesTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/EmployeesTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/EmployeesTest.java diff --git a/junit5/src/test/java/com/baeldung/ExceptionUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/ExceptionUnitTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/ExceptionUnitTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/ExceptionUnitTest.java diff --git a/junit5/src/test/java/com/baeldung/FirstUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/FirstUnitTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/FirstUnitTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/FirstUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/GreetingsTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/GreetingsTest.java new file mode 100644 index 0000000000..efde4e7404 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/GreetingsTest.java @@ -0,0 +1,19 @@ +package com.baeldung; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; + +import com.baeldung.junit5.Greetings; + +@RunWith(JUnitPlatform.class) +public class GreetingsTest { + + @Test + void whenCallingSayHello_thenReturnHello() { + assertTrue("Hello".equals(Greetings.sayHello())); + } + +} \ No newline at end of file diff --git a/junit5/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/JUnit5NewFeaturesUnitTest.java diff --git a/junit5/src/test/java/com/baeldung/LiveTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/LiveTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/LiveTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/LiveTest.java diff --git a/junit5/src/test/java/com/baeldung/NestedUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/NestedUnitTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/NestedUnitTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/NestedUnitTest.java diff --git a/junit5/src/test/java/com/baeldung/RepeatedTestExample.java b/testing-modules/junit-5/src/test/java/com/baeldung/RepeatedTestExample.java similarity index 100% rename from junit5/src/test/java/com/baeldung/RepeatedTestExample.java rename to testing-modules/junit-5/src/test/java/com/baeldung/RepeatedTestExample.java diff --git a/junit5/src/test/java/com/baeldung/StringUtils.java b/testing-modules/junit-5/src/test/java/com/baeldung/StringUtils.java similarity index 100% rename from junit5/src/test/java/com/baeldung/StringUtils.java rename to testing-modules/junit-5/src/test/java/com/baeldung/StringUtils.java diff --git a/junit5/src/test/java/com/baeldung/TaggedUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/TaggedUnitTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/TaggedUnitTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/TaggedUnitTest.java diff --git a/junit5/src/test/java/com/baeldung/TestLauncher.java b/testing-modules/junit-5/src/test/java/com/baeldung/TestLauncher.java similarity index 100% rename from junit5/src/test/java/com/baeldung/TestLauncher.java rename to testing-modules/junit-5/src/test/java/com/baeldung/TestLauncher.java diff --git a/junit5/src/test/java/com/baeldung/extensions/EmployeeDaoParameterResolver.java b/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDaoParameterResolver.java similarity index 100% rename from junit5/src/test/java/com/baeldung/extensions/EmployeeDaoParameterResolver.java rename to testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDaoParameterResolver.java diff --git a/junit5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java b/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java similarity index 100% rename from junit5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java rename to testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java diff --git a/junit5/src/test/java/com/baeldung/extensions/EnvironmentExtension.java b/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EnvironmentExtension.java similarity index 100% rename from junit5/src/test/java/com/baeldung/extensions/EnvironmentExtension.java rename to testing-modules/junit-5/src/test/java/com/baeldung/extensions/EnvironmentExtension.java diff --git a/junit5/src/test/java/com/baeldung/extensions/IgnoreFileNotFoundExceptionExtension.java b/testing-modules/junit-5/src/test/java/com/baeldung/extensions/IgnoreFileNotFoundExceptionExtension.java similarity index 100% rename from junit5/src/test/java/com/baeldung/extensions/IgnoreFileNotFoundExceptionExtension.java rename to testing-modules/junit-5/src/test/java/com/baeldung/extensions/IgnoreFileNotFoundExceptionExtension.java diff --git a/junit5/src/test/java/com/baeldung/extensions/LoggingExtension.java b/testing-modules/junit-5/src/test/java/com/baeldung/extensions/LoggingExtension.java similarity index 100% rename from junit5/src/test/java/com/baeldung/extensions/LoggingExtension.java rename to testing-modules/junit-5/src/test/java/com/baeldung/extensions/LoggingExtension.java diff --git a/junit5/src/test/java/com/baeldung/helpers/Employee.java b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/Employee.java similarity index 100% rename from junit5/src/test/java/com/baeldung/helpers/Employee.java rename to testing-modules/junit-5/src/test/java/com/baeldung/helpers/Employee.java diff --git a/junit5/src/test/java/com/baeldung/helpers/EmployeeDao.java b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeDao.java similarity index 100% rename from junit5/src/test/java/com/baeldung/helpers/EmployeeDao.java rename to testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeDao.java diff --git a/junit5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java similarity index 100% rename from junit5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java rename to testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java diff --git a/junit5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java similarity index 100% rename from junit5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java rename to testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/MockitoExtension.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/MockitoExtension.java new file mode 100644 index 0000000000..5836ef46e6 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/MockitoExtension.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015-2016 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v10.html + */ + +package com.baeldung.junit5.mockito; + +import static org.mockito.Mockito.mock; + +import java.lang.reflect.Parameter; + +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ExtensionContext.Namespace; +import org.junit.jupiter.api.extension.ExtensionContext.Store; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.jupiter.api.extension.TestInstancePostProcessor; +import org.mockito.MockitoAnnotations; +import org.mockito.Mock; + +/** + * {@code MockitoExtension} showcases the {@link TestInstancePostProcessor} + * and {@link ParameterResolver} extension APIs of JUnit 5 by providing + * dependency injection support at the field level and at the method parameter + * level via Mockito 2.x's {@link Mock @Mock} annotation. + * + * @since 5.0 + */ +public class MockitoExtension implements TestInstancePostProcessor, ParameterResolver { + + @Override + public void postProcessTestInstance(Object testInstance, ExtensionContext context) { + MockitoAnnotations.initMocks(testInstance); + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return parameterContext.getParameter().isAnnotationPresent(Mock.class); + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return getMock(parameterContext.getParameter(), extensionContext); + } + + private Object getMock(Parameter parameter, ExtensionContext extensionContext) { + Class mockType = parameter.getType(); + Store mocks = extensionContext.getStore(Namespace.create(MockitoExtension.class, mockType)); + String mockName = getMockName(parameter); + + if (mockName != null) { + return mocks.getOrComputeIfAbsent(mockName, key -> mock(mockType, mockName)); + } + else { + return mocks.getOrComputeIfAbsent(mockType.getCanonicalName(), key -> mock(mockType)); + } + } + + private String getMockName(Parameter parameter) { + String explicitMockName = parameter.getAnnotation(Mock.class).name().trim(); + if (!explicitMockName.isEmpty()) { + return explicitMockName; + } + else if (parameter.isNamePresent()) { + return parameter.getName(); + } + return null; + } + +} \ No newline at end of file diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java new file mode 100644 index 0000000000..1ddab0531a --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java @@ -0,0 +1,122 @@ +package com.baeldung.junit5.mockito; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.baeldung.junit5.mockito.repository.MailClient; +import com.baeldung.junit5.mockito.repository.SettingRepository; +import com.baeldung.junit5.mockito.repository.UserRepository; +import com.baeldung.junit5.mockito.service.DefaultUserService; +import com.baeldung.junit5.mockito.service.Errors; +import com.baeldung.junit5.mockito.service.UserService; + +@RunWith(JUnitPlatform.class) +@ExtendWith(MockitoExtension.class) +public class UserServiceUnitTest { + + UserService userService; + @Mock UserRepository userRepository; + + User user; + + @BeforeEach + void init(@Mock SettingRepository settingRepository, @Mock MailClient mailClient) { + userService = new DefaultUserService(userRepository, settingRepository, mailClient); + when(settingRepository.getUserMinAge()).thenReturn(10); + when(settingRepository.getUserNameMinLength()).thenReturn(4); + when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(false); + } + + @Test + void givenValidUser_whenSaveUser_thenSucceed(@Mock MailClient mailClient) { + // Given + user = new User("Jerry", 12); + when(userRepository.insert(any(User.class))).then(new Answer() { + int sequence = 1; + + @Override + public User answer(InvocationOnMock invocation) throws Throwable { + User user = (User) invocation.getArgument(0); + user.setId(sequence++); + return user; + } + }); + + // When + User insertedUser = userService.register(user); + + // Then + verify(userRepository).insert(user); + Assertions.assertNotNull(user.getId()); + verify(mailClient).sendUserRegistrationMail(insertedUser); + } + + @Test + void givenShortName_whenSaveUser_thenGiveShortUsernameError() { + // Given + user = new User("tom", 12); + + // When + try { + userService.register(user); + fail("Should give an error"); + } catch(Exception ex) { + assertEquals(ex.getMessage(), Errors.USER_NAME_SHORT); + } + + // Then + verify(userRepository, never()).insert(user); + } + + @Test + void givenSmallAge_whenSaveUser_thenGiveYoungUserError() { + // Given + user = new User("jerry", 3); + + // When + try { + userService.register(user); + fail("Should give an error"); + } catch(Exception ex) { + assertEquals(ex.getMessage(), Errors.USER_AGE_YOUNG); + } + + // Then + verify(userRepository, never()).insert(user); + } + + @Test + void givenUserWithExistingName_whenSaveUser_thenGiveUsernameAlreadyExistsError() { + // Given + user = new User("jerry", 12); + Mockito.reset(userRepository); + when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(true); + + // When + try { + userService.register(user); + fail("Should give an error"); + } catch(Exception ex) { + assertEquals(ex.getMessage(), Errors.USER_NAME_DUPLICATE); + } + + // Then + verify(userRepository, never()).insert(user); + } + +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/spring/GreetingsSpringTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/spring/GreetingsSpringTest.java new file mode 100644 index 0000000000..3b89508c88 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/spring/GreetingsSpringTest.java @@ -0,0 +1,21 @@ +package com.baeldung.junit5.spring; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.junit5.Greetings; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { SpringTestConfiguration.class }) +public class GreetingsSpringTest { + + @Test + void whenCallingSayHello_thenReturnHello() { + assertTrue("Hello".equals(Greetings.sayHello())); + } + +} \ No newline at end of file diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java new file mode 100644 index 0000000000..7651b2bd41 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/spring/SpringTestConfiguration.java @@ -0,0 +1,8 @@ +package com.baeldung.junit5.spring; + +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SpringTestConfiguration { + +} diff --git a/junit5/src/test/java/com/baeldung/migration/junit4/AnnotationTestExampleTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/AnnotationTestExampleTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/migration/junit4/AnnotationTestExampleTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/AnnotationTestExampleTest.java diff --git a/junit5/src/test/java/com/baeldung/migration/junit4/AssertionsExampleTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/AssertionsExampleTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/migration/junit4/AssertionsExampleTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/AssertionsExampleTest.java diff --git a/junit5/src/test/java/com/baeldung/migration/junit4/RuleExampleTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/RuleExampleTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/migration/junit4/RuleExampleTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/RuleExampleTest.java diff --git a/junit5/src/test/java/com/baeldung/migration/junit4/categories/Annotations.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/categories/Annotations.java similarity index 100% rename from junit5/src/test/java/com/baeldung/migration/junit4/categories/Annotations.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/categories/Annotations.java diff --git a/junit5/src/test/java/com/baeldung/migration/junit4/categories/JUnit4Tests.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/categories/JUnit4Tests.java similarity index 100% rename from junit5/src/test/java/com/baeldung/migration/junit4/categories/JUnit4Tests.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/categories/JUnit4Tests.java diff --git a/junit5/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java similarity index 100% rename from junit5/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit4/rules/TraceUnitTestRule.java diff --git a/junit5/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AnnotationTestExampleTest.java diff --git a/junit5/src/test/java/com/baeldung/migration/junit5/AssertionsExampleTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AssertionsExampleTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/migration/junit5/AssertionsExampleTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/AssertionsExampleTest.java diff --git a/junit5/src/test/java/com/baeldung/migration/junit5/RuleExampleTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/RuleExampleTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/migration/junit5/RuleExampleTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/RuleExampleTest.java diff --git a/junit5/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java b/testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java similarity index 100% rename from junit5/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java rename to testing-modules/junit-5/src/test/java/com/baeldung/migration/junit5/extensions/TraceUnitExtension.java diff --git a/junit5/src/test/java/com/baeldung/param/InvalidPersonParameterResolver.java b/testing-modules/junit-5/src/test/java/com/baeldung/param/InvalidPersonParameterResolver.java similarity index 100% rename from junit5/src/test/java/com/baeldung/param/InvalidPersonParameterResolver.java rename to testing-modules/junit-5/src/test/java/com/baeldung/param/InvalidPersonParameterResolver.java diff --git a/junit5/src/test/java/com/baeldung/param/Person.java b/testing-modules/junit-5/src/test/java/com/baeldung/param/Person.java similarity index 100% rename from junit5/src/test/java/com/baeldung/param/Person.java rename to testing-modules/junit-5/src/test/java/com/baeldung/param/Person.java diff --git a/junit5/src/test/java/com/baeldung/param/PersonValidator.java b/testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidator.java similarity index 100% rename from junit5/src/test/java/com/baeldung/param/PersonValidator.java rename to testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidator.java diff --git a/junit5/src/test/java/com/baeldung/param/PersonValidatorTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidatorTest.java similarity index 100% rename from junit5/src/test/java/com/baeldung/param/PersonValidatorTest.java rename to testing-modules/junit-5/src/test/java/com/baeldung/param/PersonValidatorTest.java diff --git a/junit5/src/test/java/com/baeldung/param/ValidPersonParameterResolver.java b/testing-modules/junit-5/src/test/java/com/baeldung/param/ValidPersonParameterResolver.java similarity index 100% rename from junit5/src/test/java/com/baeldung/param/ValidPersonParameterResolver.java rename to testing-modules/junit-5/src/test/java/com/baeldung/param/ValidPersonParameterResolver.java diff --git a/junit5/src/test/java/com/baeldung/suites/AllTests.java b/testing-modules/junit-5/src/test/java/com/baeldung/suites/AllTests.java similarity index 100% rename from junit5/src/test/java/com/baeldung/suites/AllTests.java rename to testing-modules/junit-5/src/test/java/com/baeldung/suites/AllTests.java diff --git a/junit5/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/testing-modules/junit-5/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension similarity index 100% rename from junit5/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension rename to testing-modules/junit-5/src/test/resources/META-INF/services/org.junit.jupiter.api.extension.Extension diff --git a/junit5/src/test/resources/com/baeldung/extensions/application.properties b/testing-modules/junit-5/src/test/resources/com/baeldung/extensions/application.properties similarity index 100% rename from junit5/src/test/resources/com/baeldung/extensions/application.properties rename to testing-modules/junit-5/src/test/resources/com/baeldung/extensions/application.properties diff --git a/junit5/src/test/resources/com/baeldung/helpers/jdbc.properties b/testing-modules/junit-5/src/test/resources/com/baeldung/helpers/jdbc.properties similarity index 100% rename from junit5/src/test/resources/com/baeldung/helpers/jdbc.properties rename to testing-modules/junit-5/src/test/resources/com/baeldung/helpers/jdbc.properties diff --git a/mockito2/.gitignore b/testing-modules/mockito-2/.gitignore similarity index 100% rename from mockito2/.gitignore rename to testing-modules/mockito-2/.gitignore diff --git a/mockito2/README.md b/testing-modules/mockito-2/README.md similarity index 100% rename from mockito2/README.md rename to testing-modules/mockito-2/README.md diff --git a/mockito2/pom.xml b/testing-modules/mockito-2/pom.xml similarity index 96% rename from mockito2/pom.xml rename to testing-modules/mockito-2/pom.xml index a7c4683c30..2d119ae8af 100644 --- a/mockito2/pom.xml +++ b/testing-modules/mockito-2/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.baeldung - mockito2 + mockito-2 0.0.1-SNAPSHOT jar mockito-2-with-java8 @@ -12,6 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/mockito2/src/main/java/com/baeldung/mockito/java8/JobPosition.java b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/java8/JobPosition.java similarity index 100% rename from mockito2/src/main/java/com/baeldung/mockito/java8/JobPosition.java rename to testing-modules/mockito-2/src/main/java/com/baeldung/mockito/java8/JobPosition.java diff --git a/mockito2/src/main/java/com/baeldung/mockito/java8/JobService.java b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/java8/JobService.java similarity index 100% rename from mockito2/src/main/java/com/baeldung/mockito/java8/JobService.java rename to testing-modules/mockito-2/src/main/java/com/baeldung/mockito/java8/JobService.java diff --git a/mockito2/src/main/java/com/baeldung/mockito/java8/Person.java b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/java8/Person.java similarity index 100% rename from mockito2/src/main/java/com/baeldung/mockito/java8/Person.java rename to testing-modules/mockito-2/src/main/java/com/baeldung/mockito/java8/Person.java diff --git a/mockito2/src/main/java/com/baeldung/mockito/java8/UnemploymentService.java b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/java8/UnemploymentService.java similarity index 100% rename from mockito2/src/main/java/com/baeldung/mockito/java8/UnemploymentService.java rename to testing-modules/mockito-2/src/main/java/com/baeldung/mockito/java8/UnemploymentService.java diff --git a/mockito2/src/main/java/com/baeldung/mockito/java8/UnemploymentServiceImpl.java b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/java8/UnemploymentServiceImpl.java similarity index 100% rename from mockito2/src/main/java/com/baeldung/mockito/java8/UnemploymentServiceImpl.java rename to testing-modules/mockito-2/src/main/java/com/baeldung/mockito/java8/UnemploymentServiceImpl.java diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithLambdaUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithLambdaUnitTest.java similarity index 100% rename from mockito2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithLambdaUnitTest.java rename to testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithLambdaUnitTest.java diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithoutLambdaUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithoutLambdaUnitTest.java similarity index 100% rename from mockito2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithoutLambdaUnitTest.java rename to testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/ArgumentMatcherWithoutLambdaUnitTest.java diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithLambdaUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithLambdaUnitTest.java similarity index 100% rename from mockito2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithLambdaUnitTest.java rename to testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithLambdaUnitTest.java diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithoutLambdaUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithoutLambdaUnitTest.java similarity index 100% rename from mockito2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithoutLambdaUnitTest.java rename to testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/CustomAnswerWithoutLambdaUnitTest.java diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/JobServiceUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/JobServiceUnitTest.java similarity index 100% rename from mockito2/src/test/java/com/baeldung/mockito/java8/JobServiceUnitTest.java rename to testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/JobServiceUnitTest.java diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/LazyVerificationTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/LazyVerificationTest.java new file mode 100644 index 0000000000..43b39d6859 --- /dev/null +++ b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/LazyVerificationTest.java @@ -0,0 +1,34 @@ +package com.baeldung.mockito.java8; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.util.List; + +import org.junit.Test; +import org.mockito.exceptions.base.MockitoAssertionError; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.VerificationCollector; + +public class LazyVerificationTest { + + @Test + public void whenLazilyVerified_thenReportsMultipleFailures() { + VerificationCollector collector = MockitoJUnit.collector() + .assertLazily(); + + List mockList = mock(List.class); + verify(mockList).add("one"); + verify(mockList).clear(); + + try { + collector.collectAndReport(); + } catch (MockitoAssertionError error) { + assertTrue(error.getMessage() + .contains("1. Wanted but not invoked:")); + assertTrue(error.getMessage() + .contains("2. Wanted but not invoked:")); + } + } +} diff --git a/mockito2/src/test/java/com/baeldung/mockito/java8/UnemploymentServiceImplUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/UnemploymentServiceImplUnitTest.java similarity index 100% rename from mockito2/src/test/java/com/baeldung/mockito/java8/UnemploymentServiceImplUnitTest.java rename to testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/UnemploymentServiceImplUnitTest.java diff --git a/testing-modules/mockito/.gitignore b/testing-modules/mockito/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/testing-modules/mockito/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/mockito/README.md b/testing-modules/mockito/README.md similarity index 75% rename from mockito/README.md rename to testing-modules/mockito/README.md index 6de2fb0c7a..0d6f69a64f 100644 --- a/mockito/README.md +++ b/testing-modules/mockito/README.md @@ -10,3 +10,5 @@ - [Mockito – @Mock, @Spy, @Captor and @InjectMocks](http://www.baeldung.com/mockito-annotations) - [Mockito’s Mock Methods](http://www.baeldung.com/mockito-mock-methods) - [Introduction to PowerMock](http://www.baeldung.com/intro-to-powermock) +- [Mocking Exception Throwing using Mockito](http://www.baeldung.com/mockito-exceptions) +- [Mocking Void Methods with Mockito](http://www.baeldung.com/mockito-void-methods) diff --git a/mockito/pom.xml b/testing-modules/mockito/pom.xml similarity index 97% rename from mockito/pom.xml rename to testing-modules/mockito/pom.xml index 19dd2f6468..0e83c46926 100644 --- a/mockito/pom.xml +++ b/testing-modules/mockito/pom.xml @@ -11,6 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/spring-security-rest-full/src/main/resources/logback.xml b/testing-modules/mockito/src/main/resources/logback.xml similarity index 100% rename from spring-security-rest-full/src/main/resources/logback.xml rename to testing-modules/mockito/src/main/resources/logback.xml diff --git a/mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorForPartialMocking.java b/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorForPartialMocking.java similarity index 100% rename from mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorForPartialMocking.java rename to testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorForPartialMocking.java diff --git a/mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorWithFinalMethods.java b/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorWithFinalMethods.java similarity index 100% rename from mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorWithFinalMethods.java rename to testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorWithFinalMethods.java diff --git a/mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorWithStaticMethods.java b/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorWithStaticMethods.java similarity index 100% rename from mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorWithStaticMethods.java rename to testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/CollaboratorWithStaticMethods.java diff --git a/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/LuckyNumberGenerator.java b/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/LuckyNumberGenerator.java new file mode 100644 index 0000000000..cfe406c112 --- /dev/null +++ b/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/LuckyNumberGenerator.java @@ -0,0 +1,28 @@ +package com.baeldung.powermockito.introduction; + +class LuckyNumberGenerator { + + public int getLuckyNumber(String name) { + + saveIntoDatabase(name); + + if (name == null) { + return getDefaultLuckyNumber(); + } + + return getComputedLuckyNumber(name.length()); + } + + private void saveIntoDatabase(String name) { + // Save the name into the database + } + + private int getDefaultLuckyNumber() { + return 100; + } + + private int getComputedLuckyNumber(int length) { + return length < 5 ? 5 : 10000; + } + +} diff --git a/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/LuckyNumberGeneratorTest.java b/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/LuckyNumberGeneratorTest.java new file mode 100644 index 0000000000..2836bcd317 --- /dev/null +++ b/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/LuckyNumberGeneratorTest.java @@ -0,0 +1,51 @@ +package com.baeldung.powermockito.introduction; + +import static org.junit.Assert.assertEquals; +import static org.powermock.api.mockito.PowerMockito.doReturn; +import static org.powermock.api.mockito.PowerMockito.spy; +import static org.powermock.api.mockito.PowerMockito.verifyPrivate; +import static org.powermock.api.mockito.PowerMockito.when; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(fullyQualifiedNames = "com.baeldung.powermockito.introduction.LuckyNumberGenerator") +public class LuckyNumberGeneratorTest { + + @Test + public final void givenPrivateMethodWithReturn_whenUsingPowerMockito_thenCorrect() throws Exception { + LuckyNumberGenerator mock = spy(new LuckyNumberGenerator()); + + when(mock, "getDefaultLuckyNumber").thenReturn(300); + + int result = mock.getLuckyNumber(null); + + assertEquals(300, result); + } + + @Test + public final void givenPrivateMethodWithArgumentAndReturn_whenUsingPowerMockito_thenCorrect() throws Exception { + LuckyNumberGenerator mock = spy(new LuckyNumberGenerator()); + + doReturn(1).when(mock, "getComputedLuckyNumber", ArgumentMatchers.anyInt()); + + int result = mock.getLuckyNumber("Jack"); + + assertEquals(1, result); + } + + @Test + public final void givenPrivateMethodWithNoArgumentAndReturn_whenUsingPowerMockito_thenCorrect() throws Exception { + LuckyNumberGenerator mock = spy(new LuckyNumberGenerator()); + + int result = mock.getLuckyNumber("Tyranosorous"); + + verifyPrivate(mock).invoke("saveIntoDatabase", ArgumentMatchers.anyString()); + assertEquals(10000, result); + } + +} diff --git a/mockito/src/test/java/com/baeldung/powermockito/introduction/PowerMockitoIntegrationTest.java b/testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/PowerMockitoIntegrationTest.java similarity index 100% rename from mockito/src/test/java/com/baeldung/powermockito/introduction/PowerMockitoIntegrationTest.java rename to testing-modules/mockito/src/test/java/com/baeldung/powermockito/introduction/PowerMockitoIntegrationTest.java diff --git a/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/BDDMockitoTest.java b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/BDDMockitoTest.java new file mode 100644 index 0000000000..9cc586fb84 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/BDDMockitoTest.java @@ -0,0 +1,104 @@ +package org.baeldung.bddmockito; + +import static org.junit.Assert.fail; +import static org.mockito.BDDMockito.*; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; + + +public class BDDMockitoTest { + + PhoneBookService phoneBookService; + PhoneBookRepository phoneBookRepository; + + String momContactName = "Mom"; + String momPhoneNumber = "01234"; + String xContactName = "x"; + String tooLongPhoneNumber = "01111111111111"; + + @Before + public void init() { + phoneBookRepository = Mockito.mock(PhoneBookRepository.class); + phoneBookService = new PhoneBookService(phoneBookRepository); + } + + @Test + public void givenValidContactName_whenSearchInPhoneBook_thenRetunPhoneNumber() { + given(phoneBookRepository.contains(momContactName)).willReturn(true); + given(phoneBookRepository.getPhoneNumberByContactName(momContactName)) + .will((InvocationOnMock invocation) -> { + if(invocation.getArgument(0).equals(momContactName)) { + return momPhoneNumber; + } else { + return null; + } + }); + + String phoneNumber = phoneBookService.search(momContactName); + + then(phoneBookRepository).should().contains(momContactName); + then(phoneBookRepository).should().getPhoneNumberByContactName(momContactName); + Assert.assertEquals(phoneNumber, momPhoneNumber); + } + + @Test + public void givenInvalidContactName_whenSearch_thenRetunNull() { + given(phoneBookRepository.contains(xContactName)).willReturn(false); + + String phoneNumber = phoneBookService.search(xContactName); + + then(phoneBookRepository).should().contains(xContactName); + then(phoneBookRepository).should(never()).getPhoneNumberByContactName(xContactName); + Assert.assertEquals(phoneNumber, null); + } + + @Test + public void givenValidContactNameAndPhoneNumber_whenRegister_thenSucceed() { + given(phoneBookRepository.contains(momContactName)).willReturn(false); + + phoneBookService.register(momContactName, momPhoneNumber); + + verify(phoneBookRepository).insert(momContactName, momPhoneNumber); + } + + @Test + public void givenEmptyPhoneNumber_whenRegister_thenFail() { + given(phoneBookRepository.contains(momContactName)).willReturn(false); + + phoneBookService.register(xContactName, ""); + + then(phoneBookRepository).should(never()).insert(momContactName, momPhoneNumber); + } + + @Test + public void givenLongPhoneNumber_whenRegister_thenFail() { + given(phoneBookRepository.contains(xContactName)).willReturn(false); + willThrow(new RuntimeException()) + .given(phoneBookRepository).insert(any(String.class), eq(tooLongPhoneNumber)); + + try { + phoneBookService.register(xContactName, tooLongPhoneNumber); + fail("Should throw exception"); + } catch (RuntimeException ex) { } + + then(phoneBookRepository).should(never()).insert(momContactName, tooLongPhoneNumber); + } + + @Test + public void givenExistentContactName_whenRegister_thenFail() { + given(phoneBookRepository.contains(momContactName)) + .willThrow(new RuntimeException("Name already exist")); + + try { + phoneBookService.register(momContactName, momPhoneNumber); + fail("Should throw exception"); + } catch(Exception ex) { } + + then(phoneBookRepository).should(never()).insert(momContactName, momPhoneNumber); + } + +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookRepository.java b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookRepository.java new file mode 100644 index 0000000000..b73a1d835c --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookRepository.java @@ -0,0 +1,26 @@ +package org.baeldung.bddmockito; + +public interface PhoneBookRepository { + + /** + * Insert phone record + * @param name Contact name + * @param phone Phone number + */ + void insert(String name, String phone); + + /** + * Search for contact phone number + * @param name Contact name + * @return phone number + */ + String getPhoneNumberByContactName(String name); + + /** + * Check if the phonebook contains this contact + * @param name Contact name + * @return true if this contact name exists + */ + boolean contains(String name); + +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookService.java b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookService.java new file mode 100644 index 0000000000..645884af02 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookService.java @@ -0,0 +1,34 @@ +package org.baeldung.bddmockito; + +public class PhoneBookService { + + private PhoneBookRepository phoneBookRepository; + + public PhoneBookService(PhoneBookRepository phoneBookRepository) { + this.phoneBookRepository = phoneBookRepository; + } + + /** + * Register a contact + * @param name Contact name + * @param phone Phone number + */ + public void register(String name, String phone) { + if(!name.isEmpty() && !phone.isEmpty() && !phoneBookRepository.contains(name)) { + phoneBookRepository.insert(name, phone); + } + } + + /** + * Search for a phone number by contact name + * @param name Contact name + * @return Phone number + */ + public String search(String name) { + if(!name.isEmpty() && phoneBookRepository.contains(name)) { + return phoneBookRepository.getPhoneNumberByContactName(name); + } + return null; + } + +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/FinalList.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/FinalList.java new file mode 100644 index 0000000000..3824de619c --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/FinalList.java @@ -0,0 +1,10 @@ +package org.baeldung.mockito; + +public class FinalList extends MyList { + + @Override + public int size() { + return 1; + } + +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockFinals.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockFinals.java new file mode 100644 index 0000000000..5f064e1355 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockFinals.java @@ -0,0 +1,35 @@ +package org.baeldung.mockito; + +import org.junit.Test; + +import static org.junit.Assert.assertNotEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class MockFinals { + + @Test + public void whenMockFinalClassMockWorks() { + + FinalList finalList = new FinalList(); + + FinalList mock = mock(FinalList.class); + when(mock.size()).thenReturn(2); + + assertNotEquals(mock.size(), finalList.size()); + + } + + @Test + public void whenMockFinalMethodMockWorks() { + + MyList myList = new MyList(); + + MyList mock = mock(MyList.class); + when(mock.finalMethod()).thenReturn(1); + + assertNotEquals(mock.finalMethod(), myList.finalMethod()); + } + + + } diff --git a/mockito/src/test/java/org/baeldung/mockito/MockitoAnnotationIntegrationTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoAnnotationIntegrationTest.java similarity index 100% rename from mockito/src/test/java/org/baeldung/mockito/MockitoAnnotationIntegrationTest.java rename to testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoAnnotationIntegrationTest.java diff --git a/mockito/src/test/java/org/baeldung/mockito/MockitoConfigExamplesIntegrationTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoConfigExamplesIntegrationTest.java similarity index 100% rename from mockito/src/test/java/org/baeldung/mockito/MockitoConfigExamplesIntegrationTest.java rename to testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoConfigExamplesIntegrationTest.java diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoExceptionIntegrationTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoExceptionIntegrationTest.java new file mode 100644 index 0000000000..9a25ccb28c --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoExceptionIntegrationTest.java @@ -0,0 +1,57 @@ +package org.baeldung.mockito; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.mockito.Mockito; + +public class MockitoExceptionIntegrationTest { + + @Test(expected = NullPointerException.class) + public void whenConfigNonVoidRetunMethodToThrowEx_thenExIsThrown() { + MyDictionary dictMock = mock(MyDictionary.class); + when(dictMock.getMeaning(anyString())).thenThrow(NullPointerException.class); + + dictMock.getMeaning("word"); + } + + @Test(expected = IllegalStateException.class) + public void whenConfigVoidRetunMethodToThrowEx_thenExIsThrown() { + MyDictionary dictMock = mock(MyDictionary.class); + doThrow(IllegalStateException.class).when(dictMock) + .add(anyString(), anyString()); + + dictMock.add("word", "meaning"); + } + + @Test(expected = NullPointerException.class) + public void whenConfigNonVoidRetunMethodToThrowExWithNewExObj_thenExIsThrown() { + MyDictionary dictMock = mock(MyDictionary.class); + when(dictMock.getMeaning(anyString())).thenThrow(new NullPointerException("Error occurred")); + + dictMock.getMeaning("word"); + } + + @Test(expected = IllegalStateException.class) + public void whenConfigVoidRetunMethodToThrowExWithNewExObj_thenExIsThrown() { + MyDictionary dictMock = mock(MyDictionary.class); + doThrow(new IllegalStateException("Error occurred")).when(dictMock) + .add(anyString(), anyString()); + + dictMock.add("word", "meaning"); + } + + // ===== + + @Test(expected = NullPointerException.class) + public void givenSpy_whenConfigNonVoidRetunMethodToThrowEx_thenExIsThrown() { + MyDictionary dict = new MyDictionary(); + MyDictionary spy = Mockito.spy(dict); + + when(spy.getMeaning(anyString())).thenThrow(NullPointerException.class); + spy.getMeaning("word"); + } +} diff --git a/mockito/src/test/java/org/baeldung/mockito/MockitoMockIntegrationTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoMockIntegrationTest.java similarity index 100% rename from mockito/src/test/java/org/baeldung/mockito/MockitoMockIntegrationTest.java rename to testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoMockIntegrationTest.java diff --git a/mockito/src/test/java/org/baeldung/mockito/MockitoSpyIntegrationTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoSpyIntegrationTest.java similarity index 100% rename from mockito/src/test/java/org/baeldung/mockito/MockitoSpyIntegrationTest.java rename to testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoSpyIntegrationTest.java diff --git a/mockito/src/test/java/org/baeldung/mockito/MockitoVerifyExamplesIntegrationTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoVerifyExamplesIntegrationTest.java similarity index 100% rename from mockito/src/test/java/org/baeldung/mockito/MockitoVerifyExamplesIntegrationTest.java rename to testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoVerifyExamplesIntegrationTest.java diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsTest.java new file mode 100644 index 0000000000..4de9a88dcc --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsTest.java @@ -0,0 +1,62 @@ +package org.baeldung.mockito; + +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.assertEquals; + +import static org.mockito.Mockito.*; +import org.mockito.ArgumentCaptor; +import static org.mockito.Matchers.any; +import org.mockito.stubbing.Answer; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class MockitoVoidMethodsTest { + + @Test + public void whenAddCalledVerified() { + MyList mockVoid = mock(MyList.class); + mockVoid.add(0, ""); + verify(mockVoid, times(1)).add(0, ""); + } + + @Test(expected = Exception.class) + public void givenNull_addThrows() { + MyList mockVoid = mock(MyList.class); + doThrow().when(mockVoid).add(isA(Integer.class), isNull()); + mockVoid.add(0, null); + } + + @Test + public void whenAddCalledValueCaptured() { + MyList mockVoid = mock(MyList.class); + ArgumentCaptor valueCapture = ArgumentCaptor.forClass(String.class); + doNothing().when(mockVoid).add(any(Integer.class), valueCapture.capture()); + mockVoid.add(0, "captured"); + assertEquals("captured", valueCapture.getValue()); + } + + @Test + public void whenAddCalledAnswered() { + MyList mockVoid = mock(MyList.class); + doAnswer((Answer) invocation -> { + Object arg0 = invocation.getArgument(0); + Object arg1 = invocation.getArgument(1); + + //do something with the arguments here + assertEquals(3, arg0); + assertEquals("answer me", arg1); + + return null; + }).when(mockVoid).add(any(Integer.class), any(String.class)); + mockVoid.add(3, "answer me"); + } + + @Test + public void whenAddCalledRealMethodCalled() { + MyList mockVoid = mock(MyList.class); + doCallRealMethod().when(mockVoid).add(any(Integer.class), any(String.class)); + mockVoid.add(1, "real"); + verify(mockVoid, times(1)).add(1, "real"); + } +} diff --git a/mockito/src/test/java/org/baeldung/mockito/MyDictionary.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyDictionary.java similarity index 100% rename from mockito/src/test/java/org/baeldung/mockito/MyDictionary.java rename to testing-modules/mockito/src/test/java/org/baeldung/mockito/MyDictionary.java diff --git a/mockito/src/test/java/org/baeldung/mockito/MyList.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyList.java similarity index 63% rename from mockito/src/test/java/org/baeldung/mockito/MyList.java rename to testing-modules/mockito/src/test/java/org/baeldung/mockito/MyList.java index be69ef8a8a..4fcddb3164 100644 --- a/mockito/src/test/java/org/baeldung/mockito/MyList.java +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyList.java @@ -14,4 +14,12 @@ class MyList extends AbstractList { return 1; } + @Override + public void add(int index, String element) { + // no-op + } + + final public int finalMethod() { + return 0; + } } diff --git a/testing-modules/mockito/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/testing-modules/mockito/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000000..ca6ee9cea8 --- /dev/null +++ b/testing-modules/mockito/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/testing-modules/mocks/README.md b/testing-modules/mocks/README.md new file mode 100644 index 0000000000..d7b817c518 --- /dev/null +++ b/testing-modules/mocks/README.md @@ -0,0 +1,6 @@ +## Relevant articles: + +- [JMockit Advanced Usage](http://www.baeldung.com/jmockit-advanced-usage) +- [A Guide to JMockit Expectations](http://www.baeldung.com/jmockit-expectations) +- [JMockit 101](http://www.baeldung.com/jmockit-101) +- [Mockito vs EasyMock vs JMockit](http://www.baeldung.com/mockito-vs-easymock-vs-jmockit) diff --git a/mocks/jmockit/README.md b/testing-modules/mocks/jmockit/README.md similarity index 100% rename from mocks/jmockit/README.md rename to testing-modules/mocks/jmockit/README.md diff --git a/mocks/jmockit/pom.xml b/testing-modules/mocks/jmockit/pom.xml similarity index 94% rename from mocks/jmockit/pom.xml rename to testing-modules/mocks/jmockit/pom.xml index 173a981e09..d998cb6918 100644 --- a/mocks/jmockit/pom.xml +++ b/testing-modules/mocks/jmockit/pom.xml @@ -6,7 +6,7 @@ com.baeldung mocks 1.0.0-SNAPSHOT - ../pom.xml + ../ jmockit diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java b/testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java similarity index 100% rename from mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java rename to testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/AdvancedCollaborator.java diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java b/testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java similarity index 100% rename from mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java rename to testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Collaborator.java diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java b/testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java similarity index 100% rename from mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java rename to testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/ExpectationsCollaborator.java diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Model.java b/testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Model.java similarity index 100% rename from mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Model.java rename to testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Model.java diff --git a/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Performer.java b/testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Performer.java similarity index 100% rename from mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Performer.java rename to testing-modules/mocks/jmockit/src/main/java/org/baeldung/mocks/jmockit/Performer.java diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorIntegrationTest.java b/testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorIntegrationTest.java similarity index 100% rename from mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorIntegrationTest.java rename to testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/AdvancedCollaboratorIntegrationTest.java diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ExpectationsIntegrationTest.java b/testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ExpectationsIntegrationTest.java similarity index 100% rename from mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ExpectationsIntegrationTest.java rename to testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ExpectationsIntegrationTest.java diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/PerformerIntegrationTest.java b/testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/PerformerIntegrationTest.java similarity index 100% rename from mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/PerformerIntegrationTest.java rename to testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/PerformerIntegrationTest.java diff --git a/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingIntegrationTest.java b/testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingIntegrationTest.java similarity index 100% rename from mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingIntegrationTest.java rename to testing-modules/mocks/jmockit/src/test/java/org/baeldung/mocks/jmockit/ReusingIntegrationTest.java diff --git a/mocks/mock-comparisons/README.md b/testing-modules/mocks/mock-comparisons/README.md similarity index 100% rename from mocks/mock-comparisons/README.md rename to testing-modules/mocks/mock-comparisons/README.md diff --git a/mocks/mock-comparisons/pom.xml b/testing-modules/mocks/mock-comparisons/pom.xml similarity index 91% rename from mocks/mock-comparisons/pom.xml rename to testing-modules/mocks/mock-comparisons/pom.xml index e350457f54..84f1d20401 100644 --- a/mocks/mock-comparisons/pom.xml +++ b/testing-modules/mocks/mock-comparisons/pom.xml @@ -6,16 +6,16 @@ com.baeldung mocks 1.0.0-SNAPSHOT - ../pom.xml + ../ mock-comparisons mock-comparisons - 2.8.9 + 2.9.0 3.4 - 1.29 + 1.34 UTF-8 diff --git a/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginController.java b/testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginController.java similarity index 100% rename from mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginController.java rename to testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginController.java diff --git a/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginDao.java b/testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginDao.java similarity index 100% rename from mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginDao.java rename to testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginDao.java diff --git a/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginService.java b/testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginService.java similarity index 100% rename from mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginService.java rename to testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/LoginService.java diff --git a/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/UserForm.java b/testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/UserForm.java similarity index 100% rename from mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/UserForm.java rename to testing-modules/mocks/mock-comparisons/src/main/java/org/baeldung/mocks/testCase/UserForm.java diff --git a/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/easymock/LoginControllerIntegrationTest.java b/testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/easymock/LoginControllerIntegrationTest.java similarity index 100% rename from mocks/mock-comparisons/src/test/java/org/baeldung/mocks/easymock/LoginControllerIntegrationTest.java rename to testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/easymock/LoginControllerIntegrationTest.java diff --git a/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/jmockit/LoginControllerIntegrationTest.java b/testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/jmockit/LoginControllerIntegrationTest.java similarity index 100% rename from mocks/mock-comparisons/src/test/java/org/baeldung/mocks/jmockit/LoginControllerIntegrationTest.java rename to testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/jmockit/LoginControllerIntegrationTest.java diff --git a/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/mockito/LoginControllerIntegrationTest.java b/testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/mockito/LoginControllerIntegrationTest.java similarity index 100% rename from mocks/mock-comparisons/src/test/java/org/baeldung/mocks/mockito/LoginControllerIntegrationTest.java rename to testing-modules/mocks/mock-comparisons/src/test/java/org/baeldung/mocks/mockito/LoginControllerIntegrationTest.java diff --git a/mocks/pom.xml b/testing-modules/mocks/pom.xml similarity index 92% rename from mocks/pom.xml rename to testing-modules/mocks/pom.xml index 84243a25d2..6473f07c13 100644 --- a/mocks/pom.xml +++ b/testing-modules/mocks/pom.xml @@ -6,7 +6,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../pom.xml + ../../ mocks diff --git a/testing-modules/mockserver/README.md b/testing-modules/mockserver/README.md new file mode 100644 index 0000000000..a8bc5cfc98 --- /dev/null +++ b/testing-modules/mockserver/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Introduction to MockServer](http://www.baeldung.com/mockserver) diff --git a/mockserver/pom.xml b/testing-modules/mockserver/pom.xml similarity index 100% rename from mockserver/pom.xml rename to testing-modules/mockserver/pom.xml diff --git a/mockserver/src/main/java/com/baeldung/mock/server/ExpectationCallbackHandler.java b/testing-modules/mockserver/src/main/java/com/baeldung/mock/server/ExpectationCallbackHandler.java similarity index 100% rename from mockserver/src/main/java/com/baeldung/mock/server/ExpectationCallbackHandler.java rename to testing-modules/mockserver/src/main/java/com/baeldung/mock/server/ExpectationCallbackHandler.java diff --git a/mockserver/src/test/java/com/baeldung/mock/server/MockServerLiveTest.java b/testing-modules/mockserver/src/test/java/com/baeldung/mock/server/MockServerLiveTest.java similarity index 100% rename from mockserver/src/test/java/com/baeldung/mock/server/MockServerLiveTest.java rename to testing-modules/mockserver/src/test/java/com/baeldung/mock/server/MockServerLiveTest.java diff --git a/rest-assured/.gitignore b/testing-modules/rest-assured/.gitignore similarity index 100% rename from rest-assured/.gitignore rename to testing-modules/rest-assured/.gitignore diff --git a/rest-assured/README.md b/testing-modules/rest-assured/README.md similarity index 100% rename from rest-assured/README.md rename to testing-modules/rest-assured/README.md diff --git a/rest-assured/pom.xml b/testing-modules/rest-assured/pom.xml similarity index 99% rename from rest-assured/pom.xml rename to testing-modules/rest-assured/pom.xml index 3fca54c80f..1006e9a373 100644 --- a/rest-assured/pom.xml +++ b/testing-modules/rest-assured/pom.xml @@ -10,6 +10,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2IntegrationTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2IntegrationTest.java new file mode 100644 index 0000000000..1b691414db --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssured2IntegrationTest.java @@ -0,0 +1,53 @@ +package com.baeldung.restassured; + +import com.github.tomakehurst.wiremock.WireMockServer; +import io.restassured.RestAssured; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static io.restassured.RestAssured.get; +import static org.hamcrest.Matchers.hasItems; + +public class RestAssured2IntegrationTest { + private static final int PORT = 8084; + private static WireMockServer wireMockServer = new WireMockServer(PORT); + + private static final String EVENTS_PATH = "/odds"; + private static final String APPLICATION_JSON = "application/json"; + private static final String ODDS = getJson(); + + @BeforeClass + public static void before() throws Exception { + System.out.println("Setting up!"); + wireMockServer.start(); + configureFor("localhost", PORT); + RestAssured.port = PORT; + stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn( + aResponse().withStatus(200) + .withHeader("Content-Type", APPLICATION_JSON) + .withBody(ODDS))); + } + + @Test + public void givenUrl_whenVerifiesOddPricesAccuratelyByStatus_thenCorrect() { + get("/odds").then().body("odds.findAll { it.status > 0 }.price", + hasItems(5.25f, 1.2f)); + } + + private static String getJson() { + return Util.inputStreamToString(RestAssured2IntegrationTest.class + .getResourceAsStream("/odds.json")); + } + + @AfterClass + public static void after() throws Exception { + System.out.println("Running: tearDown"); + wireMockServer.stop(); + } +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredIntegrationTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredIntegrationTest.java new file mode 100644 index 0000000000..4ad3cea22c --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredIntegrationTest.java @@ -0,0 +1,105 @@ +package com.baeldung.restassured; + +import com.github.fge.jsonschema.SchemaVersion; +import com.github.fge.jsonschema.cfg.ValidationConfiguration; +import com.github.fge.jsonschema.main.JsonSchemaFactory; +import com.github.tomakehurst.wiremock.WireMockServer; +import io.restassured.RestAssured; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static io.restassured.RestAssured.get; +import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath; +import static io.restassured.module.jsv.JsonSchemaValidatorSettings.settings; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItems; + +public class RestAssuredIntegrationTest { + private static final int PORT = 8083; + private static WireMockServer wireMockServer = new WireMockServer(PORT); + + private static final String EVENTS_PATH = "/events?id=390"; + private static final String APPLICATION_JSON = "application/json"; + private static final String GAME_ODDS = getEventJson(); + + @BeforeClass + public static void before() throws Exception { + System.out.println("Setting up!"); + wireMockServer.start(); + RestAssured.port = PORT; + configureFor("localhost", PORT); + stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn( + aResponse().withStatus(200) + .withHeader("Content-Type", APPLICATION_JSON) + .withBody(GAME_ODDS))); + } + + @Test + public void givenUrl_whenCheckingFloatValuePasses_thenCorrect() { + get("/events?id=390").then().assertThat() + .body("odd.ck", equalTo(12.2f)); + } + + @Test + public void givenUrl_whenSuccessOnGetsResponseAndJsonHasRequiredKV_thenCorrect() { + + get("/events?id=390").then().statusCode(200).assertThat() + .body("id", equalTo("390")); + } + + @Test + public void givenUrl_whenJsonResponseHasArrayWithGivenValuesUnderKey_thenCorrect() { + get("/events?id=390").then().assertThat() + .body("odds.price", hasItems("1.30", "5.25", "2.70", "1.20")); + } + + @Test + public void givenUrl_whenJsonResponseConformsToSchema_thenCorrect() { + + get("/events?id=390").then().assertThat() + .body(matchesJsonSchemaInClasspath("event_0.json")); + } + + @Test + public void givenUrl_whenValidatesResponseWithInstanceSettings_thenCorrect() { + JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory + .newBuilder() + .setValidationConfiguration( + ValidationConfiguration.newBuilder() + .setDefaultVersion(SchemaVersion.DRAFTV4) + .freeze()).freeze(); + + get("/events?id=390") + .then() + .assertThat() + .body(matchesJsonSchemaInClasspath("event_0.json").using( + jsonSchemaFactory)); + } + + @Test + public void givenUrl_whenValidatesResponseWithStaticSettings_thenCorrect() { + + get("/events?id=390") + .then() + .assertThat() + .body(matchesJsonSchemaInClasspath("event_0.json").using( + settings().with().checkedValidation(false))); + } + + @AfterClass + public static void after() throws Exception { + System.out.println("Running: tearDown"); + wireMockServer.stop(); + } + + private static String getEventJson() { + return Util.inputStreamToString(RestAssuredIntegrationTest.class + .getResourceAsStream("/event_0.json")); + } +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2IntegrationTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2IntegrationTest.java new file mode 100644 index 0000000000..4a29d8832f --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXML2IntegrationTest.java @@ -0,0 +1,55 @@ +package com.baeldung.restassured; + +import com.github.tomakehurst.wiremock.WireMockServer; +import io.restassured.RestAssured; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static io.restassured.RestAssured.get; +import static org.hamcrest.Matchers.hasItems; + +public class RestAssuredXML2IntegrationTest { + private static final int PORT = 8082; + private static WireMockServer wireMockServer = new WireMockServer(PORT); + + private static final String EVENTS_PATH = "/teachers"; + private static final String APPLICATION_XML = "application/xml"; + private static final String TEACHERS = getXml(); + + @BeforeClass + public static void before() throws Exception { + System.out.println("Setting up!"); + wireMockServer.start(); + RestAssured.port = PORT; + configureFor("localhost", PORT); + stubFor(get(urlEqualTo(EVENTS_PATH)).willReturn( + aResponse().withStatus(200) + .withHeader("Content-Type", APPLICATION_XML) + .withBody(TEACHERS))); + } + + @Test + public void givenUrl_whenVerifiesScienceTeacherFromXml_thenCorrect() { + get("/teachers") + .then() + .body("teachers.teacher.find { it.@department == 'science' }.subject", + hasItems("math", "physics")); + } + + private static String getXml() { + return Util.inputStreamToString(RestAssuredXML2IntegrationTest.class + .getResourceAsStream("/teachers.xml")); + } + + @AfterClass + public static void after() throws Exception { + System.out.println("Running: tearDown"); + wireMockServer.stop(); + } +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLIntegrationTest.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLIntegrationTest.java new file mode 100644 index 0000000000..f1a22831f4 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/RestAssuredXMLIntegrationTest.java @@ -0,0 +1,90 @@ +package com.baeldung.restassured; + +import com.github.tomakehurst.wiremock.WireMockServer; +import io.restassured.RestAssured; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.configureFor; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static io.restassured.RestAssured.post; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.xml.HasXPath.hasXPath; + +public class RestAssuredXMLIntegrationTest { + private static final int PORT = 8081; + private static WireMockServer wireMockServer = new WireMockServer(PORT); + + private static final String EVENTS_PATH = "/employees"; + private static final String APPLICATION_XML = "application/xml"; + private static final String EMPLOYEES = getXml(); + + @BeforeClass + public static void before() throws Exception { + System.out.println("Setting up!"); + wireMockServer.start(); + configureFor("localhost", PORT); + RestAssured.port = PORT; + stubFor(post(urlEqualTo(EVENTS_PATH)).willReturn( + aResponse().withStatus(200) + .withHeader("Content-Type", APPLICATION_XML) + .withBody(EMPLOYEES))); + } + + @Test + public void givenUrl_whenXmlResponseValueTestsEqual_thenCorrect() { + post("/employees").then().assertThat() + .body("employees.employee.first-name", equalTo("Jane")); + } + + @Test + public void givenUrl_whenMultipleXmlValuesTestEqual_thenCorrect() { + post("/employees").then().assertThat() + .body("employees.employee.first-name", equalTo("Jane")) + .body("employees.employee.last-name", equalTo("Daisy")) + .body("employees.employee.sex", equalTo("f")); + } + + @Test + public void givenUrl_whenMultipleXmlValuesTestEqualInShortHand_thenCorrect() { + post("/employees") + .then() + .assertThat() + .body("employees.employee.first-name", equalTo("Jane"), + "employees.employee.last-name", equalTo("Daisy"), + "employees.employee.sex", equalTo("f")); + } + + @Test + public void givenUrl_whenValidatesXmlUsingXpath_thenCorrect() { + post("/employees") + .then() + .assertThat() + .body(hasXPath("/employees/employee/first-name", + containsString("Ja"))); + } + + @Test + public void givenUrl_whenValidatesXmlUsingXpath2_thenCorrect() { + post("/employees") + .then() + .assertThat() + .body(hasXPath("/employees/employee/first-name[text()='Jane']")); + } + + private static String getXml() { + return Util + .inputStreamToString(RestAssuredXMLIntegrationTest.class.getResourceAsStream("/employees.xml")); + } + + @AfterClass + public static void after() throws Exception { + System.out.println("Running: tearDown"); + wireMockServer.stop(); + } +} diff --git a/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/Util.java b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/Util.java new file mode 100644 index 0000000000..02dec87927 --- /dev/null +++ b/testing-modules/rest-assured/src/test/java/com/baeldung/restassured/Util.java @@ -0,0 +1,15 @@ +package com.baeldung.restassured; + +import java.io.InputStream; +import java.util.Scanner; + +final class Util { + + private Util() { + } + + static String inputStreamToString(InputStream is) { + Scanner s = new Scanner(is).useDelimiter("\\A"); + return s.hasNext() ? s.next() : ""; + } +} diff --git a/rest-assured/src/test/resources/employees.xml b/testing-modules/rest-assured/src/test/resources/employees.xml similarity index 100% rename from rest-assured/src/test/resources/employees.xml rename to testing-modules/rest-assured/src/test/resources/employees.xml diff --git a/rest-assured/src/test/resources/event_0.json b/testing-modules/rest-assured/src/test/resources/event_0.json similarity index 100% rename from rest-assured/src/test/resources/event_0.json rename to testing-modules/rest-assured/src/test/resources/event_0.json diff --git a/testing-modules/rest-assured/src/test/resources/logback.xml b/testing-modules/rest-assured/src/test/resources/logback.xml new file mode 100644 index 0000000000..ec0dc2469a --- /dev/null +++ b/testing-modules/rest-assured/src/test/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rest-assured/src/test/resources/odds.json b/testing-modules/rest-assured/src/test/resources/odds.json similarity index 100% rename from rest-assured/src/test/resources/odds.json rename to testing-modules/rest-assured/src/test/resources/odds.json diff --git a/rest-assured/src/test/resources/teachers.xml b/testing-modules/rest-assured/src/test/resources/teachers.xml similarity index 100% rename from rest-assured/src/test/resources/teachers.xml rename to testing-modules/rest-assured/src/test/resources/teachers.xml diff --git a/rest-testing/.gitignore b/testing-modules/rest-testing/.gitignore similarity index 100% rename from rest-testing/.gitignore rename to testing-modules/rest-testing/.gitignore diff --git a/rest-testing/README.md b/testing-modules/rest-testing/README.md similarity index 85% rename from rest-testing/README.md rename to testing-modules/rest-testing/README.md index 37a53dd815..c6185de05f 100644 --- a/rest-testing/README.md +++ b/testing-modules/rest-testing/README.md @@ -10,3 +10,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Introduction to WireMock](http://www.baeldung.com/introduction-to-wiremock) - [REST API Testing with Cucumber](http://www.baeldung.com/cucumber-rest-api-testing) - [Testing a REST API with JBehave](http://www.baeldung.com/jbehave-rest-testing) +- [REST API Testing with Karate](http://www.baeldung.com/karate-rest-api-testing) diff --git a/rest-testing/pom.xml b/testing-modules/rest-testing/pom.xml similarity index 91% rename from rest-testing/pom.xml rename to testing-modules/rest-testing/pom.xml index b99dfac571..ea63ee0e58 100644 --- a/rest-testing/pom.xml +++ b/testing-modules/rest-testing/pom.xml @@ -11,6 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ @@ -88,6 +89,19 @@ ${jbehave.version} test + + + com.intuit.karate + karate-apache + ${karate.version} + + + + com.intuit.karate + karate-junit4 + ${karate.version} + test + @@ -150,6 +164,7 @@ 2.9.0 1.2.5 2.4.1 + 0.6.1 4.4.5 4.5.2 diff --git a/rest-testing/src/main/resources/cucumber.json b/testing-modules/rest-testing/src/main/resources/cucumber.json similarity index 100% rename from rest-testing/src/main/resources/cucumber.json rename to testing-modules/rest-testing/src/main/resources/cucumber.json diff --git a/rest-testing/src/main/resources/Feature/cucumber.feature b/testing-modules/rest-testing/src/main/resources/karate/cucumber.feature similarity index 100% rename from rest-testing/src/main/resources/Feature/cucumber.feature rename to testing-modules/rest-testing/src/main/resources/karate/cucumber.feature diff --git a/testing-modules/rest-testing/src/main/resources/logback.xml b/testing-modules/rest-testing/src/main/resources/logback.xml new file mode 100644 index 0000000000..ec0dc2469a --- /dev/null +++ b/testing-modules/rest-testing/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rest-testing/src/main/resources/wiremock_intro.json b/testing-modules/rest-testing/src/main/resources/wiremock_intro.json similarity index 100% rename from rest-testing/src/main/resources/wiremock_intro.json rename to testing-modules/rest-testing/src/main/resources/wiremock_intro.json diff --git a/rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberIntegrationTest.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberIntegrationTest.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberIntegrationTest.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/cucumber/CucumberIntegrationTest.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/cucumber/StepDefinition.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/AbstractStory.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/AbstractStory.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/jbehave/AbstractStory.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/AbstractStory.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundSteps.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundSteps.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundSteps.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundSteps.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundStoryLiveTest.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundStoryLiveTest.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundStoryLiveTest.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundStoryLiveTest.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeSteps.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeSteps.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeSteps.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeSteps.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeStoryLiveTest.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeStoryLiveTest.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeStoryLiveTest.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeStoryLiveTest.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadSteps.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadSteps.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadSteps.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadSteps.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadStoryLiveTest.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadStoryLiveTest.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadStoryLiveTest.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadStoryLiveTest.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseSteps.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseSteps.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseSteps.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseSteps.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseStoryLiveTest.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseStoryLiveTest.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseStoryLiveTest.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseStoryLiveTest.java diff --git a/testing-modules/rest-testing/src/test/java/com/baeldung/rest/karate/KarateUnitTest.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/karate/KarateUnitTest.java new file mode 100644 index 0000000000..f942721504 --- /dev/null +++ b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/karate/KarateUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.rest.karate; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.intuit.karate.junit4.Karate; +import cucumber.api.CucumberOptions; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.runner.RunWith; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; + +@RunWith(Karate.class) +@CucumberOptions(features = "classpath:karate") +public class KarateUnitTest { + + private static final WireMockServer wireMockServer = new WireMockServer(); + + @BeforeClass + public static void setUp() throws Exception { + wireMockServer.start(); + + configureFor("localhost", 8080); + stubFor(get(urlEqualTo("/user/get")) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("{ \"id\": \"1234\", name: \"John Smith\" }"))); + stubFor(post(urlEqualTo("/user/create")) + .withHeader("content-type", equalTo("application/json")) + .withRequestBody(containing("id")) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("{ \"id\": \"1234\", name: \"John Smith\" }"))); + + } + + @AfterClass + public static void tearDown() throws Exception { + wireMockServer.stop(); + } + +} diff --git a/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManagedIntegrationTest.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManagedIntegrationTest.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManagedIntegrationTest.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/JUnitManagedIntegrationTest.java diff --git a/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/ProgrammaticallyManagedLiveTest.java b/testing-modules/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/ProgrammaticallyManagedLiveTest.java similarity index 100% rename from rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/ProgrammaticallyManagedLiveTest.java rename to testing-modules/rest-testing/src/test/java/com/baeldung/rest/wiremock/introduction/ProgrammaticallyManagedLiveTest.java diff --git a/rest-testing/src/test/java/org/baeldung/rest/GitHubUser.java b/testing-modules/rest-testing/src/test/java/org/baeldung/rest/GitHubUser.java similarity index 100% rename from rest-testing/src/test/java/org/baeldung/rest/GitHubUser.java rename to testing-modules/rest-testing/src/test/java/org/baeldung/rest/GitHubUser.java diff --git a/rest-testing/src/test/java/org/baeldung/rest/GithubBasicLiveTest.java b/testing-modules/rest-testing/src/test/java/org/baeldung/rest/GithubBasicLiveTest.java similarity index 100% rename from rest-testing/src/test/java/org/baeldung/rest/GithubBasicLiveTest.java rename to testing-modules/rest-testing/src/test/java/org/baeldung/rest/GithubBasicLiveTest.java diff --git a/rest-testing/src/test/java/org/baeldung/rest/RetrieveUtil.java b/testing-modules/rest-testing/src/test/java/org/baeldung/rest/RetrieveUtil.java similarity index 100% rename from rest-testing/src/test/java/org/baeldung/rest/RetrieveUtil.java rename to testing-modules/rest-testing/src/test/java/org/baeldung/rest/RetrieveUtil.java diff --git a/rest-testing/src/test/resources/github_user_not_found.story b/testing-modules/rest-testing/src/test/resources/github_user_not_found.story similarity index 100% rename from rest-testing/src/test/resources/github_user_not_found.story rename to testing-modules/rest-testing/src/test/resources/github_user_not_found.story diff --git a/rest-testing/src/test/resources/github_user_response_mediatype.story b/testing-modules/rest-testing/src/test/resources/github_user_response_mediatype.story similarity index 100% rename from rest-testing/src/test/resources/github_user_response_mediatype.story rename to testing-modules/rest-testing/src/test/resources/github_user_response_mediatype.story diff --git a/rest-testing/src/test/resources/github_user_response_payload.story b/testing-modules/rest-testing/src/test/resources/github_user_response_payload.story similarity index 100% rename from rest-testing/src/test/resources/github_user_response_payload.story rename to testing-modules/rest-testing/src/test/resources/github_user_response_payload.story diff --git a/rest-testing/src/test/resources/increase.story b/testing-modules/rest-testing/src/test/resources/increase.story similarity index 100% rename from rest-testing/src/test/resources/increase.story rename to testing-modules/rest-testing/src/test/resources/increase.story diff --git a/testing-modules/rest-testing/src/test/resources/karate/user.feature b/testing-modules/rest-testing/src/test/resources/karate/user.feature new file mode 100644 index 0000000000..d9f0f12a9c --- /dev/null +++ b/testing-modules/rest-testing/src/test/resources/karate/user.feature @@ -0,0 +1,42 @@ +Feature: Testing a REST API with Karate + +Scenario: Testing valid GET endpoint + Given url 'http://localhost:8080/user/get' + When method GET + Then status 200 + +Scenario: Testing an invalid GET endpoint - 404 + Given url 'http://localhost:8080/user/wrong' + When method GET + Then status 404 + +Scenario: Testing the exact response of a GET endpoint + Given url 'http://localhost:8080/user/get' + When method GET + Then status 200 + And match $ == {id:"1234",name:"John Smith"} + +Scenario: Testing the exact response field value of a GET endpoint + Given url 'http://localhost:8080/user/get' + When method GET + Then status 200 + And match $.id == "1234" + +Scenario: Testing that GET response contains specific field + Given url 'http://localhost:8080/user/get' + When method GET + Then status 200 + And match $ contains {id:"1234"} + +Scenario: Test GET response using markers + Given url 'http://localhost:8080/user/get' + When method GET + Then status 200 + And match $ == {id:"#notnull",name:"John Smith"} + +Scenario: Testing a POST endpoint with request body + Given url 'http://localhost:8080/user/create' + And request { id: '1234' , name: 'John Smith'} + When method POST + Then status 200 + And match $ contains {id:"#notnull"} diff --git a/selenium-junit-testng/README.md b/testing-modules/selenium-junit-testng/README.md similarity index 77% rename from selenium-junit-testng/README.md rename to testing-modules/selenium-junit-testng/README.md index 29393b956b..0137212290 100644 --- a/selenium-junit-testng/README.md +++ b/testing-modules/selenium-junit-testng/README.md @@ -1,4 +1,3 @@ ### Relevant Articles: - [Guide to Selenium with JUnit / TestNG](http://www.baeldung.com/java-selenium-with-junit-and-testng) -- [Testing a Site with Selenium / Webdriver](http://www.baeldung.com) - [Testing with Selenium/WebDriver and the Page Object Pattern](http://www.baeldung.com/selenium-webdriver-page-object) diff --git a/selenium-junit-testng/geckodriver.mac b/testing-modules/selenium-junit-testng/geckodriver.mac similarity index 100% rename from selenium-junit-testng/geckodriver.mac rename to testing-modules/selenium-junit-testng/geckodriver.mac diff --git a/selenium-junit-testng/pom.xml b/testing-modules/selenium-junit-testng/pom.xml similarity index 96% rename from selenium-junit-testng/pom.xml rename to testing-modules/selenium-junit-testng/pom.xml index 5b695ca900..418dd495a4 100644 --- a/selenium-junit-testng/pom.xml +++ b/testing-modules/selenium-junit-testng/pom.xml @@ -9,6 +9,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ @@ -27,7 +28,6 @@ **/*LiveTest.java - false diff --git a/selenium-junit-testng/src/main/java/com/baeldung/selenium/SeleniumExample.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/SeleniumExample.java similarity index 100% rename from selenium-junit-testng/src/main/java/com/baeldung/selenium/SeleniumExample.java rename to testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/SeleniumExample.java diff --git a/selenium-junit-testng/src/main/java/com/baeldung/selenium/config/SeleniumConfig.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/config/SeleniumConfig.java similarity index 100% rename from selenium-junit-testng/src/main/java/com/baeldung/selenium/config/SeleniumConfig.java rename to testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/config/SeleniumConfig.java diff --git a/selenium-junit-testng/src/main/java/com/baeldung/selenium/models/BaeldungAbout.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/models/BaeldungAbout.java similarity index 100% rename from selenium-junit-testng/src/main/java/com/baeldung/selenium/models/BaeldungAbout.java rename to testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/models/BaeldungAbout.java diff --git a/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungAboutPage.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungAboutPage.java similarity index 100% rename from selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungAboutPage.java rename to testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungAboutPage.java diff --git a/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungHomePage.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungHomePage.java similarity index 100% rename from selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungHomePage.java rename to testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/BaeldungHomePage.java diff --git a/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/StartHerePage.java b/testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/StartHerePage.java similarity index 100% rename from selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/StartHerePage.java rename to testing-modules/selenium-junit-testng/src/main/java/com/baeldung/selenium/pages/StartHerePage.java diff --git a/selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumPageObjectLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumPageObjectLiveTest.java similarity index 100% rename from selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumPageObjectLiveTest.java rename to testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumPageObjectLiveTest.java diff --git a/selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumWithJUnitLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumWithJUnitLiveTest.java similarity index 100% rename from selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumWithJUnitLiveTest.java rename to testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/junit/SeleniumWithJUnitLiveTest.java diff --git a/selenium-junit-testng/src/test/java/com/baeldung/selenium/testng/SeleniumWithTestNGLiveTest.java b/testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/testng/SeleniumWithTestNGLiveTest.java similarity index 100% rename from selenium-junit-testng/src/test/java/com/baeldung/selenium/testng/SeleniumWithTestNGLiveTest.java rename to testing-modules/selenium-junit-testng/src/test/java/com/baeldung/selenium/testng/SeleniumWithTestNGLiveTest.java diff --git a/testing/README.md b/testing-modules/testing/README.md similarity index 79% rename from testing/README.md rename to testing-modules/testing/README.md index a691737e4f..143cb792cf 100644 --- a/testing/README.md +++ b/testing-modules/testing/README.md @@ -13,3 +13,6 @@ - [Testing with JGoTesting](http://www.baeldung.com/jgotesting) - [Introduction to JUnitParams](http://www.baeldung.com/junit-params) - [Cucumber Java 8 Support](http://www.baeldung.com/cucumber-java-8-support) +- [Introduction to Lambda Behave](http://www.baeldung.com/lambda-behave) +- [Introduction to Jukito](http://www.baeldung.com/jukito) +- [Custom JUnit 4 Test Runners](http://www.baeldung.com/junit-4-custom-runners) diff --git a/testing/pom.xml b/testing-modules/testing/pom.xml similarity index 95% rename from testing/pom.xml rename to testing-modules/testing/pom.xml index 72ec2b2f0c..7aff0a93e0 100644 --- a/testing/pom.xml +++ b/testing-modules/testing/pom.xml @@ -10,6 +10,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ @@ -86,6 +87,12 @@ jgotesting ${jgotesting.version} test + + + org.jukito + jukito + 1.5 + test diff --git a/testing/src/main/java/com/baeldung/cucumber/Calculator.java b/testing-modules/testing/src/main/java/com/baeldung/cucumber/Calculator.java similarity index 100% rename from testing/src/main/java/com/baeldung/cucumber/Calculator.java rename to testing-modules/testing/src/main/java/com/baeldung/cucumber/Calculator.java diff --git a/testing-modules/testing/src/main/java/com/baeldung/introductionjukito/Calculator.java b/testing-modules/testing/src/main/java/com/baeldung/introductionjukito/Calculator.java new file mode 100644 index 0000000000..fd75e1bd9e --- /dev/null +++ b/testing-modules/testing/src/main/java/com/baeldung/introductionjukito/Calculator.java @@ -0,0 +1,7 @@ +package com.baeldung.introductionjukito; + +public interface Calculator { + + public double add(double a, double b); + +} diff --git a/testing-modules/testing/src/main/java/com/baeldung/introductionjukito/ScientificCalculator.java b/testing-modules/testing/src/main/java/com/baeldung/introductionjukito/ScientificCalculator.java new file mode 100644 index 0000000000..2501569afc --- /dev/null +++ b/testing-modules/testing/src/main/java/com/baeldung/introductionjukito/ScientificCalculator.java @@ -0,0 +1,5 @@ +package com.baeldung.introductionjukito; + +public class ScientificCalculator extends SimpleCalculator { + +} diff --git a/testing-modules/testing/src/main/java/com/baeldung/introductionjukito/SimpleCalculator.java b/testing-modules/testing/src/main/java/com/baeldung/introductionjukito/SimpleCalculator.java new file mode 100644 index 0000000000..933baa3cd0 --- /dev/null +++ b/testing-modules/testing/src/main/java/com/baeldung/introductionjukito/SimpleCalculator.java @@ -0,0 +1,10 @@ +package com.baeldung.introductionjukito; + +public class SimpleCalculator implements Calculator { + + @Override + public double add(double a, double b) { + return a+b; + } + +} diff --git a/testing-modules/testing/src/main/java/com/baeldung/junit/Calculator.java b/testing-modules/testing/src/main/java/com/baeldung/junit/Calculator.java new file mode 100644 index 0000000000..8ea7b3ed1f --- /dev/null +++ b/testing-modules/testing/src/main/java/com/baeldung/junit/Calculator.java @@ -0,0 +1,11 @@ +package com.baeldung.junit; + +public class Calculator { + public int add(int a, int b) { + return a + b; + } + + public int sub(int a, int b) { + return a - b; + } +} diff --git a/testing/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java b/testing-modules/testing/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java similarity index 100% rename from testing/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java rename to testing-modules/testing/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java diff --git a/testing/src/main/java/com/baeldung/lambdabehave/Calculator.java b/testing-modules/testing/src/main/java/com/baeldung/lambdabehave/Calculator.java similarity index 100% rename from testing/src/main/java/com/baeldung/lambdabehave/Calculator.java rename to testing-modules/testing/src/main/java/com/baeldung/lambdabehave/Calculator.java diff --git a/testing/src/main/java/com/baeldung/testing/assertj/Dog.java b/testing-modules/testing/src/main/java/com/baeldung/testing/assertj/Dog.java similarity index 100% rename from testing/src/main/java/com/baeldung/testing/assertj/Dog.java rename to testing-modules/testing/src/main/java/com/baeldung/testing/assertj/Dog.java diff --git a/testing/src/main/java/com/baeldung/testing/assertj/Person.java b/testing-modules/testing/src/main/java/com/baeldung/testing/assertj/Person.java similarity index 100% rename from testing/src/main/java/com/baeldung/testing/assertj/Person.java rename to testing-modules/testing/src/main/java/com/baeldung/testing/assertj/Person.java diff --git a/testing/src/main/java/com/baeldung/testing/mutation/Palindrome.java b/testing-modules/testing/src/main/java/com/baeldung/testing/mutation/Palindrome.java similarity index 100% rename from testing/src/main/java/com/baeldung/testing/mutation/Palindrome.java rename to testing-modules/testing/src/main/java/com/baeldung/testing/mutation/Palindrome.java diff --git a/testing/src/main/java/com/baeldung/testing/truth/User.java b/testing-modules/testing/src/main/java/com/baeldung/testing/truth/User.java similarity index 100% rename from testing/src/main/java/com/baeldung/testing/truth/User.java rename to testing-modules/testing/src/main/java/com/baeldung/testing/truth/User.java diff --git a/testing/src/main/java/com/baeldung/testing/truth/UserSubject.java b/testing-modules/testing/src/main/java/com/baeldung/testing/truth/UserSubject.java similarity index 100% rename from testing/src/main/java/com/baeldung/testing/truth/UserSubject.java rename to testing-modules/testing/src/main/java/com/baeldung/testing/truth/UserSubject.java diff --git a/testing-modules/testing/src/test/java/com/baeldung/introductionjukito/CalculatorTest.java b/testing-modules/testing/src/test/java/com/baeldung/introductionjukito/CalculatorTest.java new file mode 100644 index 0000000000..313e1d2938 --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/introductionjukito/CalculatorTest.java @@ -0,0 +1,62 @@ +package com.baeldung.introductionjukito; + +import org.jukito.All; +import org.jukito.JukitoModule; +import org.jukito.JukitoRunner; +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.*; + +@RunWith(JukitoRunner.class) +public class CalculatorTest { + + public static class Module extends JukitoModule { + + @Override + protected void configureTest() { + bindMany(Calculator.class, SimpleCalculator.class, + ScientificCalculator.class); + bindManyInstances(AdditionTest.class, new AdditionTest(1, 1, 2), + new AdditionTest(10, 10, 20), + new AdditionTest(18, 24, 42)); + bindManyNamedInstances(Integer.class, "even", 2, 4, 6); + bindManyNamedInstances(Integer.class, "odd", 1, 3, 5); + } + } + + public static class AdditionTest { + + int a; + int b; + int expected; + + public AdditionTest(int a, int b, int expected) { + this.a = a; + this.b = b; + this.expected = expected; + } + } + + @Test + public void givenTwoNumbers_WhenAdd_ThenSumBoth(@All Calculator calc) { + double result = calc.add(1, 1); + assertEquals(2, result, .1); + } + + @Test + public void givenTwoNumbers_WhenAdd_ThenSumBoth(@All Calculator calc, + @All AdditionTest addTest) { + double result = calc.add(addTest.a, addTest.b); + assertEquals(addTest.expected, result, .1); + } + + @Test + public void givenEvenNumbers_whenPrint_thenOutput(@All("even") Integer i) { + System.out.println("even " + i); + } + + @Test + public void givenOddNumbers_whenPrint_thenOutput(@All("odd") Integer i) { + System.out.println("odd " + i); + } +} diff --git a/testing-modules/testing/src/test/java/com/baeldung/junit/AdditionTest.java b/testing-modules/testing/src/test/java/com/baeldung/junit/AdditionTest.java new file mode 100644 index 0000000000..0d492f8058 --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/junit/AdditionTest.java @@ -0,0 +1,14 @@ +package com.baeldung.junit; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class AdditionTest { + Calculator calculator = new Calculator(); + + @Test + public void testAddition() { + assertEquals("addition", 8, calculator.add(5, 3)); + } +} diff --git a/testing-modules/testing/src/test/java/com/baeldung/junit/BlockingTestRunner.java b/testing-modules/testing/src/test/java/com/baeldung/junit/BlockingTestRunner.java new file mode 100644 index 0000000000..432d5cda83 --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/junit/BlockingTestRunner.java @@ -0,0 +1,18 @@ +package com.baeldung.junit; + +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.Statement; + +public class BlockingTestRunner extends BlockJUnit4ClassRunner { + public BlockingTestRunner(Class klass) throws InitializationError { + super(klass); + } + + @Override + protected Statement methodInvoker(FrameworkMethod method, Object test) { + System.out.println("invoking: " + method.getName()); + return super.methodInvoker(method, test); + } +} diff --git a/testing-modules/testing/src/test/java/com/baeldung/junit/CalculatorTest.java b/testing-modules/testing/src/test/java/com/baeldung/junit/CalculatorTest.java new file mode 100644 index 0000000000..d1b35d1442 --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/junit/CalculatorTest.java @@ -0,0 +1,17 @@ +package com.baeldung.junit; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import static org.junit.Assert.assertEquals; + +@RunWith(JUnit4.class) +public class CalculatorTest { + Calculator calculator = new Calculator(); + + @Test + public void testAddition() { + assertEquals("addition", 8, calculator.add(5, 3)); + } +} diff --git a/testing-modules/testing/src/test/java/com/baeldung/junit/SubstractionTest.java b/testing-modules/testing/src/test/java/com/baeldung/junit/SubstractionTest.java new file mode 100644 index 0000000000..9650d83afe --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/junit/SubstractionTest.java @@ -0,0 +1,14 @@ +package com.baeldung.junit; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SubstractionTest { + Calculator calculator = new Calculator(); + + @Test + public void substraction() { + assertEquals("substraction", 2, calculator.sub(5, 3)); + } +} diff --git a/testing-modules/testing/src/test/java/com/baeldung/junit/SuiteTest.java b/testing-modules/testing/src/test/java/com/baeldung/junit/SuiteTest.java new file mode 100644 index 0000000000..428319e72e --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/junit/SuiteTest.java @@ -0,0 +1,12 @@ +package com.baeldung.junit; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ + AdditionTest.class, + SubstractionTest.class}) +public class SuiteTest { +} diff --git a/testing-modules/testing/src/test/java/com/baeldung/junit/TestRunner.java b/testing-modules/testing/src/test/java/com/baeldung/junit/TestRunner.java new file mode 100644 index 0000000000..9eb4b3141b --- /dev/null +++ b/testing-modules/testing/src/test/java/com/baeldung/junit/TestRunner.java @@ -0,0 +1,41 @@ +package com.baeldung.junit; + +import org.junit.Test; +import org.junit.runner.Description; +import org.junit.runner.Runner; +import org.junit.runner.notification.RunNotifier; + +import java.lang.reflect.Method; + +public class TestRunner extends Runner { + + private Class testClass; + public TestRunner(Class testClass) { + super(); + this.testClass = testClass; + } + + @Override + public Description getDescription() { + return Description.createTestDescription(testClass, "My runner description"); + } + + @Override + public void run(RunNotifier notifier) { + System.out.println("running the tests from MyRunner: " + testClass); + try { + Object testObject = testClass.newInstance(); + for (Method method : testClass.getMethods()) { + if (method.isAnnotationPresent(Test.class)) { + notifier.fireTestStarted(Description + .createTestDescription(testClass, method.getName())); + method.invoke(testObject); + notifier.fireTestFinished(Description + .createTestDescription(testClass, method.getName())); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/testing/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java b/testing-modules/testing/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java similarity index 100% rename from testing/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java rename to testing-modules/testing/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java diff --git a/testing/src/test/java/com/baeldung/junitparams/TestDataProvider.java b/testing-modules/testing/src/test/java/com/baeldung/junitparams/TestDataProvider.java similarity index 100% rename from testing/src/test/java/com/baeldung/junitparams/TestDataProvider.java rename to testing-modules/testing/src/test/java/com/baeldung/junitparams/TestDataProvider.java diff --git a/testing/src/test/java/com/baeldung/lambdabehave/CalculatorTest.java b/testing-modules/testing/src/test/java/com/baeldung/lambdabehave/CalculatorTest.java similarity index 100% rename from testing/src/test/java/com/baeldung/lambdabehave/CalculatorTest.java rename to testing-modules/testing/src/test/java/com/baeldung/lambdabehave/CalculatorTest.java diff --git a/testing/src/test/java/com/baeldung/mutation/test/PalindromeUnitTest.java b/testing-modules/testing/src/test/java/com/baeldung/mutation/test/PalindromeUnitTest.java similarity index 100% rename from testing/src/test/java/com/baeldung/mutation/test/PalindromeUnitTest.java rename to testing-modules/testing/src/test/java/com/baeldung/mutation/test/PalindromeUnitTest.java diff --git a/testing/src/test/java/com/baeldung/testing/assertj/AssertJCoreUnitTest.java b/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/AssertJCoreUnitTest.java similarity index 100% rename from testing/src/test/java/com/baeldung/testing/assertj/AssertJCoreUnitTest.java rename to testing-modules/testing/src/test/java/com/baeldung/testing/assertj/AssertJCoreUnitTest.java diff --git a/testing/src/test/java/com/baeldung/testing/assertj/AssertJGuavaUnitTest.java b/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/AssertJGuavaUnitTest.java similarity index 100% rename from testing/src/test/java/com/baeldung/testing/assertj/AssertJGuavaUnitTest.java rename to testing-modules/testing/src/test/java/com/baeldung/testing/assertj/AssertJGuavaUnitTest.java diff --git a/testing/src/test/java/com/baeldung/testing/assertj/AssertJJava8UnitTest.java b/testing-modules/testing/src/test/java/com/baeldung/testing/assertj/AssertJJava8UnitTest.java similarity index 100% rename from testing/src/test/java/com/baeldung/testing/assertj/AssertJJava8UnitTest.java rename to testing-modules/testing/src/test/java/com/baeldung/testing/assertj/AssertJJava8UnitTest.java diff --git a/testing/src/test/java/com/baeldung/testing/calculator/CalculatorIntegrationTest.java b/testing-modules/testing/src/test/java/com/baeldung/testing/calculator/CalculatorIntegrationTest.java similarity index 100% rename from testing/src/test/java/com/baeldung/testing/calculator/CalculatorIntegrationTest.java rename to testing-modules/testing/src/test/java/com/baeldung/testing/calculator/CalculatorIntegrationTest.java diff --git a/testing/src/test/java/com/baeldung/testing/calculator/CalculatorRunSteps.java b/testing-modules/testing/src/test/java/com/baeldung/testing/calculator/CalculatorRunSteps.java similarity index 100% rename from testing/src/test/java/com/baeldung/testing/calculator/CalculatorRunSteps.java rename to testing-modules/testing/src/test/java/com/baeldung/testing/calculator/CalculatorRunSteps.java diff --git a/testing/src/test/java/com/baeldung/testing/jgotesting/JGoTestingUnitTest.java b/testing-modules/testing/src/test/java/com/baeldung/testing/jgotesting/JGoTestingUnitTest.java similarity index 100% rename from testing/src/test/java/com/baeldung/testing/jgotesting/JGoTestingUnitTest.java rename to testing-modules/testing/src/test/java/com/baeldung/testing/jgotesting/JGoTestingUnitTest.java diff --git a/testing/src/test/java/com/baeldung/testing/shopping/ShoppingIntegrationTest.java b/testing-modules/testing/src/test/java/com/baeldung/testing/shopping/ShoppingIntegrationTest.java similarity index 100% rename from testing/src/test/java/com/baeldung/testing/shopping/ShoppingIntegrationTest.java rename to testing-modules/testing/src/test/java/com/baeldung/testing/shopping/ShoppingIntegrationTest.java diff --git a/testing/src/test/java/com/baeldung/testing/shopping/ShoppingStepsDef.java b/testing-modules/testing/src/test/java/com/baeldung/testing/shopping/ShoppingStepsDef.java similarity index 100% rename from testing/src/test/java/com/baeldung/testing/shopping/ShoppingStepsDef.java rename to testing-modules/testing/src/test/java/com/baeldung/testing/shopping/ShoppingStepsDef.java diff --git a/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java b/testing-modules/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java similarity index 100% rename from testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java rename to testing-modules/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java diff --git a/testing/src/test/resources/JunitParamsTestParameters.csv b/testing-modules/testing/src/test/resources/JunitParamsTestParameters.csv similarity index 100% rename from testing/src/test/resources/JunitParamsTestParameters.csv rename to testing-modules/testing/src/test/resources/JunitParamsTestParameters.csv diff --git a/testing/src/test/resources/features/calculator-scenario-outline.feature b/testing-modules/testing/src/test/resources/features/calculator-scenario-outline.feature similarity index 100% rename from testing/src/test/resources/features/calculator-scenario-outline.feature rename to testing-modules/testing/src/test/resources/features/calculator-scenario-outline.feature diff --git a/testing/src/test/resources/features/calculator.feature b/testing-modules/testing/src/test/resources/features/calculator.feature similarity index 100% rename from testing/src/test/resources/features/calculator.feature rename to testing-modules/testing/src/test/resources/features/calculator.feature diff --git a/testing/src/test/resources/features/shopping.feature b/testing-modules/testing/src/test/resources/features/shopping.feature similarity index 100% rename from testing/src/test/resources/features/shopping.feature rename to testing-modules/testing/src/test/resources/features/shopping.feature diff --git a/testng/README.md b/testing-modules/testng/README.md similarity index 100% rename from testng/README.md rename to testing-modules/testng/README.md diff --git a/testng/pom.xml b/testing-modules/testng/pom.xml similarity index 94% rename from testng/pom.xml rename to testing-modules/testng/pom.xml index 0ca775a00c..7aed1837e5 100644 --- a/testng/pom.xml +++ b/testing-modules/testng/pom.xml @@ -11,6 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../../ diff --git a/testng/src/test/java/com/baeldung/DependentLongRunningUnitTest.java b/testing-modules/testng/src/test/java/com/baeldung/DependentLongRunningUnitTest.java similarity index 100% rename from testng/src/test/java/com/baeldung/DependentLongRunningUnitTest.java rename to testing-modules/testng/src/test/java/com/baeldung/DependentLongRunningUnitTest.java diff --git a/testng/src/test/java/com/baeldung/GroupIntegrationTest.java b/testing-modules/testng/src/test/java/com/baeldung/GroupIntegrationTest.java similarity index 100% rename from testng/src/test/java/com/baeldung/GroupIntegrationTest.java rename to testing-modules/testng/src/test/java/com/baeldung/GroupIntegrationTest.java diff --git a/testng/src/test/java/com/baeldung/MultiThreadedIntegrationTest.java b/testing-modules/testng/src/test/java/com/baeldung/MultiThreadedIntegrationTest.java similarity index 100% rename from testng/src/test/java/com/baeldung/MultiThreadedIntegrationTest.java rename to testing-modules/testng/src/test/java/com/baeldung/MultiThreadedIntegrationTest.java diff --git a/testng/src/test/java/com/baeldung/ParametrizedLongRunningUnitTest.java b/testing-modules/testng/src/test/java/com/baeldung/ParametrizedLongRunningUnitTest.java similarity index 100% rename from testng/src/test/java/com/baeldung/ParametrizedLongRunningUnitTest.java rename to testing-modules/testng/src/test/java/com/baeldung/ParametrizedLongRunningUnitTest.java diff --git a/testng/src/test/java/com/baeldung/PriorityLongRunningUnitTest.java b/testing-modules/testng/src/test/java/com/baeldung/PriorityLongRunningUnitTest.java similarity index 100% rename from testng/src/test/java/com/baeldung/PriorityLongRunningUnitTest.java rename to testing-modules/testng/src/test/java/com/baeldung/PriorityLongRunningUnitTest.java diff --git a/testng/src/test/java/com/baeldung/RegistrationLongRunningUnitTest.java b/testing-modules/testng/src/test/java/com/baeldung/RegistrationLongRunningUnitTest.java similarity index 100% rename from testng/src/test/java/com/baeldung/RegistrationLongRunningUnitTest.java rename to testing-modules/testng/src/test/java/com/baeldung/RegistrationLongRunningUnitTest.java diff --git a/testng/src/test/java/com/baeldung/SignInLongRunningUnitTest.java b/testing-modules/testng/src/test/java/com/baeldung/SignInLongRunningUnitTest.java similarity index 100% rename from testng/src/test/java/com/baeldung/SignInLongRunningUnitTest.java rename to testing-modules/testng/src/test/java/com/baeldung/SignInLongRunningUnitTest.java diff --git a/testng/src/test/java/com/baeldung/SimpleLongRunningUnitTest.java b/testing-modules/testng/src/test/java/com/baeldung/SimpleLongRunningUnitTest.java similarity index 100% rename from testng/src/test/java/com/baeldung/SimpleLongRunningUnitTest.java rename to testing-modules/testng/src/test/java/com/baeldung/SimpleLongRunningUnitTest.java diff --git a/testng/src/test/java/com/baeldung/SummationServiceIntegrationTest.java b/testing-modules/testng/src/test/java/com/baeldung/SummationServiceIntegrationTest.java similarity index 100% rename from testng/src/test/java/com/baeldung/SummationServiceIntegrationTest.java rename to testing-modules/testng/src/test/java/com/baeldung/SummationServiceIntegrationTest.java diff --git a/testng/src/test/java/com/baeldung/TimeOutIntegrationTest.java b/testing-modules/testng/src/test/java/com/baeldung/TimeOutIntegrationTest.java similarity index 100% rename from testng/src/test/java/com/baeldung/TimeOutIntegrationTest.java rename to testing-modules/testng/src/test/java/com/baeldung/TimeOutIntegrationTest.java diff --git a/testng/src/test/java/com/baeldung/reports/CustomisedListener.java b/testing-modules/testng/src/test/java/com/baeldung/reports/CustomisedListener.java similarity index 100% rename from testng/src/test/java/com/baeldung/reports/CustomisedListener.java rename to testing-modules/testng/src/test/java/com/baeldung/reports/CustomisedListener.java diff --git a/testng/src/test/java/com/baeldung/reports/CustomisedReports.java b/testing-modules/testng/src/test/java/com/baeldung/reports/CustomisedReports.java similarity index 100% rename from testng/src/test/java/com/baeldung/reports/CustomisedReports.java rename to testing-modules/testng/src/test/java/com/baeldung/reports/CustomisedReports.java diff --git a/testng/src/test/resources/logback.xml b/testing-modules/testng/src/test/resources/logback.xml similarity index 100% rename from testng/src/test/resources/logback.xml rename to testing-modules/testng/src/test/resources/logback.xml diff --git a/testng/src/test/resources/parametrized_testng.xml b/testing-modules/testng/src/test/resources/parametrized_testng.xml similarity index 100% rename from testng/src/test/resources/parametrized_testng.xml rename to testing-modules/testng/src/test/resources/parametrized_testng.xml diff --git a/testng/src/test/resources/reportTemplate.html b/testing-modules/testng/src/test/resources/reportTemplate.html similarity index 100% rename from testng/src/test/resources/reportTemplate.html rename to testing-modules/testng/src/test/resources/reportTemplate.html diff --git a/testng/src/test/resources/test_group.xml b/testing-modules/testng/src/test/resources/test_group.xml similarity index 100% rename from testng/src/test/resources/test_group.xml rename to testing-modules/testng/src/test/resources/test_group.xml diff --git a/testng/src/test/resources/test_setup.xml b/testing-modules/testng/src/test/resources/test_setup.xml similarity index 100% rename from testng/src/test/resources/test_setup.xml rename to testing-modules/testng/src/test/resources/test_setup.xml diff --git a/testng/src/test/resources/test_suite.xml b/testing-modules/testng/src/test/resources/test_suite.xml similarity index 100% rename from testng/src/test/resources/test_suite.xml rename to testing-modules/testng/src/test/resources/test_suite.xml diff --git a/undertow/README.md b/undertow/README.md new file mode 100644 index 0000000000..8bfb4832e2 --- /dev/null +++ b/undertow/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to JBoss Undertow](http://www.baeldung.com/jboss-undertow) diff --git a/undertow/dependency-reduced-pom.xml b/undertow/dependency-reduced-pom.xml new file mode 100644 index 0000000000..0654c82b74 --- /dev/null +++ b/undertow/dependency-reduced-pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + com.baeldung.undertow + undertow + undertow + 1.0-SNAPSHOT + http://maven.apache.org + + ${project.artifactId} + + + maven-shade-plugin + + + package + + shade + + + + + + maven-jar-plugin + + + + com.baeldung.undertow.SimpleServer + + + + + + + + 1.8 + 1.8 + + + diff --git a/vaadin/README.md b/vaadin/README.md new file mode 100644 index 0000000000..0dfeea8996 --- /dev/null +++ b/vaadin/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Introduction to Vaadin](http://www.baeldung.com/vaadin) diff --git a/vavr/README.md b/vavr/README.md index d7816f3f9f..4361363fbd 100644 --- a/vavr/README.md +++ b/vavr/README.md @@ -5,4 +5,6 @@ - [Property Testing Example With Vavr](http://www.baeldung.com/javaslang-property-testing) - [Exceptions in Lambda Expression Using Vavr](http://www.baeldung.com/exceptions-using-vavr) - [Vavr (ex-Javaslang) Support in Spring Data](http://www.baeldung.com/spring-vavr) - +- [Introduction to Vavr’s Validation API](http://www.baeldung.com/vavr-validation-api) +- [Guide to Collections API in Vavr](http://www.baeldung.com/vavr-collections) +- [Collection Factory Methods for Vavr](http://www.baeldung.com/vavr-collection-factory-methods) diff --git a/vavr/pom.xml b/vavr/pom.xml index 53cd07ddf7..f9fed7d4fc 100644 --- a/vavr/pom.xml +++ b/vavr/pom.xml @@ -5,12 +5,13 @@ vavr 1.0 vavr - + org.springframework.boot spring-boot-starter-parent - 2.0.0.BUILD-SNAPSHOT - + 1.5.6.RELEASE + + @@ -35,10 +36,11 @@ com.h2database h2 - + org.springframework.boot spring-boot-starter-test + test @@ -74,7 +76,7 @@ 1.8 - 0.9.0 + 0.9.1 4.12 3.0.0 @@ -95,7 +97,7 @@ **/JdbcTest.java **/*LiveTest.java - true + diff --git a/vavr/src/test/java/com/baeldung/vavr/collections/CollectionFactoryMethodsUnitTest.java b/vavr/src/test/java/com/baeldung/vavr/collections/CollectionFactoryMethodsUnitTest.java new file mode 100644 index 0000000000..60359d6803 --- /dev/null +++ b/vavr/src/test/java/com/baeldung/vavr/collections/CollectionFactoryMethodsUnitTest.java @@ -0,0 +1,107 @@ +package com.baeldung.vavr.collections; + +import static io.vavr.API.Array; +import static io.vavr.API.Failure; +import static io.vavr.API.List; +import static io.vavr.API.None; +import static io.vavr.API.Some; +import static io.vavr.API.Stream; +import static io.vavr.API.Success; +import static io.vavr.API.Tuple; +import static io.vavr.API.Vector; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import io.vavr.Tuple3; +import io.vavr.collection.Array; +import io.vavr.collection.List; +import io.vavr.collection.Stream; +import io.vavr.collection.Vector; +import io.vavr.control.Option; +import io.vavr.control.Try; + +public class CollectionFactoryMethodsUnitTest { + + @Test + public void givenANoneOptionElement_whenCreated_thenCorrect() { + Option none = None(); + assertFalse(none == null); + assertEquals(none, Option.none()); + } + + @Test + public void givenASomeOptionElement_whenCreated_thenCorrect() { + Option some = Some(1); + assertFalse(some == null); + assertTrue(some.contains(1)); + } + + @Test + public void givenATupleElement_whenCreated_thenCorrect() { + Tuple3 tuple = Tuple('a', "chain", 2); + assertTrue(tuple!=null); + assertEquals(tuple._1(), new Character('a')); + assertEquals(tuple._2(), "chain"); + assertEquals(tuple._3().intValue(), 2); + } + + @Test + public void givenASuccessObject_whenEvaluated_thenSuccess() { + Try integer = Success(55); + assertEquals(integer.get().intValue(), 55); + } + @Test + public void givenAFailureObject_whenEvaluated_thenExceptionThrown() { + Try failure = Failure(new Exception("Exception X encapsulated here")); + + try { + Integer i = failure.get();// evaluate a failure raise the exception + System.out.println(i);// not executed + } catch (Exception e) { + assertEquals(e.getMessage(), "Exception X encapsulated here"); + } + } + + @Test + public void givenAList_whenCreated_thenCorrect() { + List list = List(1, 2, 3, 4, 5); + + assertEquals(list.size(), 5); + assertEquals(list.get(0).intValue(), 1); + } + + @Test + public void givenAnEmptyList_whenCreated_thenCorrect() { + List empty = List(); + + assertEquals(empty.size(), 0); + assertEquals(empty, List.empty()); + } + + @Test + public void givenAnArray_whenCreated_thenCorrect() { + Array array = Array(1, 2, 3, 4, 5); + + assertEquals(array.size(), 5); + assertEquals(array.get(0).intValue(), 1); + } + + @Test + public void givenAStream_whenCreated_thenCorrect() { + Stream stream = Stream(1, 2, 3, 4, 5); + + assertEquals(stream.size(), 5); + assertEquals(stream.get(0).intValue(), 1); + } + + @Test + public void givenAVector_whenCreated_thenCorrect() { + Vector vector = Vector(1, 2, 3, 4, 5); + + assertEquals(vector.size(), 5); + assertEquals(vector.get(0).intValue(), 1); + } +} diff --git a/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java b/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java index 84621e3a68..437742c964 100644 --- a/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java +++ b/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java @@ -5,17 +5,23 @@ import static io.vavr.API.Case; import static io.vavr.API.Match; import static io.vavr.Predicates.exists; import static io.vavr.Predicates.forAll; -import static org.awaitility.Awaitility.await; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.concurrent.CancellationException; +import java.util.function.Consumer; import java.util.function.Predicate; import org.junit.Test; +import org.mockito.Mockito; +import org.mockito.internal.verification.VerificationModeFactory; +import org.mockito.verification.Timeout; +import io.vavr.Tuple; +import io.vavr.Tuple2; import io.vavr.collection.List; import io.vavr.concurrent.Future; +import io.vavr.control.Try; public class FutureUnitTest { @@ -26,8 +32,7 @@ public class FutureUnitTest { public void givenFunctionReturnInteger_WhenCallWithFuture_ShouldReturnFunctionValue() { Future future = Future.of(() -> 1); - assertEquals(1, future.get() - .intValue()); + assertEquals(1, future.get().intValue()); } @Test @@ -57,33 +62,29 @@ public class FutureUnitTest { @Test public void givenFunction_WhenCallWithFutureAndRegisterConsumerForSuccess_ShouldCallConsumerToStoreValue() { - final int[] store = new int[] { 0 }; Future future = Future.of(() -> 1); - future.onSuccess(i -> { - store[0] = i; - }); - await().until(() -> store[0] == 1); + MockConsumer consumer = Mockito.mock(MockConsumer.class); + future.onSuccess(consumer); + Mockito.verify(consumer, new Timeout(1000, VerificationModeFactory.times(1))).accept(1); } @Test public void givenFunctionThrowException_WhenCallWithFutureAndRegisterConsumerForFailer_ShouldCallConsumerToStoreException() { - final Throwable[] store = new Throwable[] { null }; Future future = Future.of(() -> getResourceThrowException("")); - future.onFailure(err -> store[0] = err); - await().until(() -> RuntimeException.class.isInstance(store[0])); + MockThrowableConsumer consumer = Mockito.mock(MockThrowableConsumer.class); + future.onFailure(consumer); + Mockito.verify(consumer, new Timeout(1000, VerificationModeFactory.times(1))).accept(Mockito.any()); } @Test public void givenAFuture_WhenAddAndThenConsumer_ShouldCallConsumerWithResultOfFutureAction() { - int[] store1 = new int[1]; - int[] store2 = new int[1]; + MockTryConsumer consumer1 = Mockito.mock(MockTryConsumer.class); + MockTryConsumer consumer2 = Mockito.mock(MockTryConsumer.class); Future future = Future.of(() -> 1); - Future andThenFuture = future.andThen(i -> store1[0] = i.get() + 1) - .andThen(i -> store2[0] = store1[0] + 1); + Future andThenFuture = future.andThen(consumer1).andThen(consumer2); andThenFuture.await(); - - assertEquals(2, store1[0]); - assertEquals(3, store2[0]); + Mockito.verify(consumer1, VerificationModeFactory.times(1)).accept(Try.success(1)); + Mockito.verify(consumer2, VerificationModeFactory.times(1)).accept(Try.success(1)); } @Test @@ -91,8 +92,7 @@ public class FutureUnitTest { Future future = Future.failed(new RuntimeException()); Future future2 = future.orElse(Future.of(() -> 2)); - assertEquals(2, future2.get() - .intValue()); + assertEquals(2, future2.get().intValue()); } @Test(expected = CancellationException.class) @@ -124,17 +124,46 @@ public class FutureUnitTest { Future future = Future.failed(new RuntimeException()); Future fallbackFuture = Future.of(() -> expectedResult); Future futureResult = future.fallbackTo(fallbackFuture); - futureResult.await(); assertEquals(expectedResult, futureResult.get()); } + + @Test + public void givenAFuture_WhenTransformByAddingOne_ShouldReturn() { + Future future = Future.of(() -> 1).transformValue(f -> Try.of(() -> "Hello: " + f.get())); + + assertEquals("Hello: 1", future.get()); + } + + @Test + public void givenAFutureOfInt_WhenMapToString_ShouldCombineAndReturn() { + Future future = Future.of(()->1).map(i -> "Hello: " + i); + + assertEquals("Hello: 1", future.get()); + } + + @Test + public void givenAFutureOfInt_WhenFlatMapToString_ShouldCombineAndReturn() { + Future futureMap = Future.of(() -> 1).flatMap((i) -> Future.of(() -> "Hello: " + i)); + + assertEquals("Hello: 1", futureMap.get()); + } + + @Test + public void givenAFutureOf2String_WhenZip_ShouldReturnTupleOf2String() { + Future> future = Future.of(() -> "hello").zip(Future.of(() -> "world")); + + assertEquals(Tuple.of("hello", "world"), future.get()); + } @Test public void givenGetResourceWithFuture_WhenWaitAndMatchWithPredicate_ShouldReturnSuccess() { String url = "http://resource"; Future future = Future.of(() -> getResource(url)); future.await(); - String s = Match(future).of(Case($(future0 -> future0.isSuccess()), SUCCESS), Case($(), FAILURE)); + String s = Match(future).of( + Case($(future0 -> future0.isSuccess()), SUCCESS), + Case($(), FAILURE)); assertEquals(SUCCESS, s); } @@ -143,7 +172,9 @@ public class FutureUnitTest { public void givenAFailedFuture_WhenWaitAndMatchWithPredicateCheckSuccess_ShouldReturnFailed() { Future future = Future.failed(new RuntimeException()); future.await(); - String s = Match(future).of(Case($(future0 -> future0.isSuccess()), SUCCESS), Case($(), FAILURE)); + String s = Match(future).of( + Case($(future0 -> future0.isSuccess()), SUCCESS), + Case($(), FAILURE)); assertEquals(FAILURE, s); } @@ -155,7 +186,10 @@ public class FutureUnitTest { return 1; }); Predicate> predicate = f -> f.exists(i -> i % 2 == 1); - String s = Match(future).of(Case($(predicate), "Even"), Case($(), "Odd")); + + String s = Match(future).of( + Case($(predicate), "Even"), + Case($(), "Odd")); assertEquals("Even", s); } @@ -164,7 +198,9 @@ public class FutureUnitTest { public void givenAListOfFutureReturnFist3Integers_WhenMatchWithExistEvenNumberPredicate_ShouldReturnSuccess() { List> futures = getFutureOfFirst3Number(); Predicate> predicate0 = future -> future.exists(i -> i % 2 == 0); - String s = Match(futures).of(Case($(exists(predicate0)), "Even"), Case($(), "Odd")); + String s = Match(futures).of( + Case($(exists(predicate0)), "Even"), + Case($(), "Odd")); assertEquals("Even", s); } @@ -173,7 +209,9 @@ public class FutureUnitTest { public void givenAListOfFutureReturnFist3Integers_WhenMatchWithForAllNumberBiggerThanZeroPredicate_ShouldReturnSuccess() { List> futures = getFutureOfFirst3Number(); Predicate> predicate0 = future -> future.exists(i -> i > 0); - String s = Match(futures).of(Case($(forAll(predicate0)), "Positive numbers"), Case($(), "None")); + String s = Match(futures).of( + Case($(forAll(predicate0)), "Positive numbers"), + Case($(), "None")); assertEquals("Positive numbers", s); } @@ -182,13 +220,19 @@ public class FutureUnitTest { public void givenAListOfFutureReturnFist3Integers_WhenMatchWithForAllNumberSmallerThanZeroPredicate_ShouldReturnFailed() { List> futures = getFutureOfFirst3Number(); Predicate> predicate0 = future -> future.exists(i -> i < 0); - String s = Match(futures).of(Case($(forAll(predicate0)), "Negative numbers"), Case($(), "None")); + String s = Match(futures).of( + Case($(forAll(predicate0)), "Negative numbers"), + Case($(), "None")); assertEquals("None", s); } - private String getResource(String url) throws InterruptedException { - Thread.sleep(10); + private String getResource(String url) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } return "Content from " + url; } @@ -200,4 +244,46 @@ public class FutureUnitTest { List> futures = List.of(Future.of(() -> 1), Future.of(() -> 2), Future.of(() -> 3)); return futures; } + + private static void checkOnSuccessFunction() { + Future future = Future.of(() -> 1); + future.onSuccess(i -> System.out.println("Future finish with result: " + i)); + } + + private static void checkOnFailureFunction() { + Future future = Future.of(() -> {throw new RuntimeException("Failed");}); + future.onFailure(t -> System.out.println("Future failures with exception: " + t)); + } + + private static void runAndThenConsumer() { + Future future = Future.of(() -> 1); + future.andThen(i -> System.out.println("Do side-effect action 1 with input: " + i.get())). + andThen((i) -> System.out.println("Do side-effect action 2 with input: " + i.get())); + } + + public static void main(String[] args) throws InterruptedException { + checkOnSuccessFunction(); + checkOnFailureFunction(); + runAndThenConsumer(); + Thread.sleep(1000); + } +} + + +class MockConsumer implements Consumer { + @Override + public void accept(Integer t) { + } +} + +class MockTryConsumer implements Consumer> { + @Override + public void accept(Try t) { + } +} + +class MockThrowableConsumer implements Consumer { + @Override + public void accept(Throwable t) { + } } diff --git a/vavr/src/test/java/com/baeldung/vavr/repositories/VavrRepositoryIntegrationTest.java b/vavr/src/test/java/com/baeldung/vavr/repositories/VavrRepositoryIntegrationTest.java index 63338afc24..7c00d46aa8 100644 --- a/vavr/src/test/java/com/baeldung/vavr/repositories/VavrRepositoryIntegrationTest.java +++ b/vavr/src/test/java/com/baeldung/vavr/repositories/VavrRepositoryIntegrationTest.java @@ -43,5 +43,4 @@ public class VavrRepositoryIntegrationTest { Seq users = userRepository.findByName("John"); assertEquals(2, users.size()); } - } diff --git a/vertx-and-rxjava/README.md b/vertx-and-rxjava/README.md new file mode 100644 index 0000000000..ccd4ce3457 --- /dev/null +++ b/vertx-and-rxjava/README.md @@ -0,0 +1,2 @@ +### Relevant articles +- [Example of Vertx and RxJava Integration](http://www.baeldung.com/vertx-rx-java) diff --git a/video-tutorials/README.md b/video-tutorials/README.md new file mode 100644 index 0000000000..ff12555376 --- /dev/null +++ b/video-tutorials/README.md @@ -0,0 +1 @@ +## Relevant articles: diff --git a/xml/src/test/resources/example_dom4j_new.xml b/xml/src/test/resources/example_dom4j_new.xml new file mode 100644 index 0000000000..020760fdd3 --- /dev/null +++ b/xml/src/test/resources/example_dom4j_new.xml @@ -0,0 +1,10 @@ + + + + + XML with Dom4J + XML handling with Dom4J + 14/06/2016 + Dom4J tech writer + + diff --git a/xml/src/test/resources/example_jaxb_new.xml b/xml/src/test/resources/example_jaxb_new.xml new file mode 100644 index 0000000000..646d938869 --- /dev/null +++ b/xml/src/test/resources/example_jaxb_new.xml @@ -0,0 +1,9 @@ + + + + Jaxb author + 04/02/2015 + XML Binding with Jaxb + XML with Jaxb + + diff --git a/xmlunit2/README.md b/xmlunit-2/README.md similarity index 100% rename from xmlunit2/README.md rename to xmlunit-2/README.md diff --git a/xmlunit2/pom.xml b/xmlunit-2/pom.xml similarity index 96% rename from xmlunit2/pom.xml rename to xmlunit-2/pom.xml index dd9fe9ac27..591cb70ec8 100644 --- a/xmlunit2/pom.xml +++ b/xmlunit-2/pom.xml @@ -2,7 +2,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 com.baeldung - xmlunit2 + xmlunit-2 1.0 XMLUnit-2 diff --git a/xmlunit2/src/main/java/com/baeldung/xmlunit/IgnoreAttributeDifferenceEvaluator.java b/xmlunit-2/src/main/java/com/baeldung/xmlunit/IgnoreAttributeDifferenceEvaluator.java similarity index 100% rename from xmlunit2/src/main/java/com/baeldung/xmlunit/IgnoreAttributeDifferenceEvaluator.java rename to xmlunit-2/src/main/java/com/baeldung/xmlunit/IgnoreAttributeDifferenceEvaluator.java diff --git a/xmlunit2/src/test/java/com/baeldung/xmlunit/XMLUnitTest.java b/xmlunit-2/src/test/java/com/baeldung/xmlunit/XMLUnitTest.java similarity index 100% rename from xmlunit2/src/test/java/com/baeldung/xmlunit/XMLUnitTest.java rename to xmlunit-2/src/test/java/com/baeldung/xmlunit/XMLUnitTest.java diff --git a/xmlunit2/src/test/resources/control.xml b/xmlunit-2/src/test/resources/control.xml similarity index 100% rename from xmlunit2/src/test/resources/control.xml rename to xmlunit-2/src/test/resources/control.xml diff --git a/xmlunit2/src/test/resources/students.xml b/xmlunit-2/src/test/resources/students.xml similarity index 100% rename from xmlunit2/src/test/resources/students.xml rename to xmlunit-2/src/test/resources/students.xml diff --git a/xmlunit2/src/test/resources/students.xsd b/xmlunit-2/src/test/resources/students.xsd similarity index 100% rename from xmlunit2/src/test/resources/students.xsd rename to xmlunit-2/src/test/resources/students.xsd diff --git a/xmlunit2/src/test/resources/students_with_error.xml b/xmlunit-2/src/test/resources/students_with_error.xml similarity index 100% rename from xmlunit2/src/test/resources/students_with_error.xml rename to xmlunit-2/src/test/resources/students_with_error.xml diff --git a/xmlunit2/src/test/resources/teachers.xml b/xmlunit-2/src/test/resources/teachers.xml similarity index 100% rename from xmlunit2/src/test/resources/teachers.xml rename to xmlunit-2/src/test/resources/teachers.xml diff --git a/xmlunit2/src/test/resources/test.xml b/xmlunit-2/src/test/resources/test.xml similarity index 100% rename from xmlunit2/src/test/resources/test.xml rename to xmlunit-2/src/test/resources/test.xml