UoWFile, minor: java 7 changes, 2.0 usage, formatting
Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/b049e9b6 Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/b049e9b6 Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/b049e9b6 Branch: refs/heads/master Commit: b049e9b65dcc7aec927e6c424d39c15069289104 Parents: b65ecb6 Author: Paul Merlin <[email protected]> Authored: Thu Feb 20 22:07:09 2014 +0100 Committer: Paul Merlin <[email protected]> Committed: Thu Feb 20 22:07:09 2014 +0100 ---------------------------------------------------------------------- .../uowfile/bootstrap/UoWFileAssembler.java | 18 +- .../ConcurrentUoWFileModificationException.java | 22 +- ...urrentUoWFileStateModificationException.java | 22 +- .../qi4j/library/uowfile/internal/UoWFile.java | 72 ++++-- .../uowfile/internal/UoWFileException.java | 22 +- .../uowfile/internal/UoWFileFactory.java | 105 ++++---- .../library/uowfile/plural/HasUoWFiles.java | 28 ++- .../uowfile/plural/HasUoWFilesLifecycle.java | 43 ++-- .../library/uowfile/plural/UoWFilesLocator.java | 20 +- .../library/uowfile/singular/HasUoWFile.java | 26 +- .../uowfile/singular/HasUoWFileLifecycle.java | 32 +-- .../uowfile/singular/UoWFileLocator.java | 20 +- .../library/uowfile/AbstractUoWFileTest.java | 60 +++-- .../qi4j/library/uowfile/HasUoWFileTest.java | 240 ++++++++++-------- .../qi4j/library/uowfile/HasUoWFilesTest.java | 248 +++++++++++-------- 15 files changed, 550 insertions(+), 428 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/bootstrap/UoWFileAssembler.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/bootstrap/UoWFileAssembler.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/bootstrap/UoWFileAssembler.java index 020d458..c6feabc 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/bootstrap/UoWFileAssembler.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/bootstrap/UoWFileAssembler.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.bootstrap; http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/ConcurrentUoWFileModificationException.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/ConcurrentUoWFileModificationException.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/ConcurrentUoWFileModificationException.java index 2bc1700..1350011 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/ConcurrentUoWFileModificationException.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/ConcurrentUoWFileModificationException.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.internal; @@ -18,9 +22,8 @@ import org.qi4j.api.entity.EntityComposite; import org.qi4j.api.unitofwork.ConcurrentEntityModificationException; public class ConcurrentUoWFileModificationException - extends ConcurrentEntityModificationException + extends ConcurrentEntityModificationException { - private final Iterable<UoWFile> concurrentlyModifiedFiles; ConcurrentUoWFileModificationException( Iterable<UoWFile> concurrentlyModifiedFiles ) @@ -39,5 +42,4 @@ public class ConcurrentUoWFileModificationException { return "Files changed concurently: " + concurrentlyModifiedFiles; } - } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/ConcurrentUoWFileStateModificationException.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/ConcurrentUoWFileStateModificationException.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/ConcurrentUoWFileStateModificationException.java index 862f348..7c09144 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/ConcurrentUoWFileStateModificationException.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/ConcurrentUoWFileStateModificationException.java @@ -1,22 +1,25 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.internal; class ConcurrentUoWFileStateModificationException - extends Exception + extends Exception { - private final UoWFile file; ConcurrentUoWFileStateModificationException( UoWFile file ) @@ -34,5 +37,4 @@ class ConcurrentUoWFileStateModificationException { return "UoWFile modified concurently: " + file.toString(); } - } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFile.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFile.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFile.java index f6ab6e8..f8b0bb8 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFile.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFile.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.internal; @@ -23,7 +27,6 @@ import org.slf4j.LoggerFactory; public class UoWFile { - /* package */ static final Logger LOGGER = LoggerFactory.getLogger( "org.qi4j.library.uowfile" ); private static final int FILE_BUFFER_SIZE = 4096; private static final AtomicLong COUNT = new AtomicLong( 0L ); @@ -52,33 +55,38 @@ public class UoWFile StringBuilder sb = new StringBuilder().append( UoWFile.class.getSimpleName() ); // UoWFile{parent/( original(oid->id) | current(id) | backup(id) )} sb.append( "{" ).append( original.getParentFile().getName() ).append( "/( " ). - append( original.getName() ).append( "(" ).append( originalIdentity ).append( "->" ).append( fileTag( original ) ).append( ") | " ). - append( current.getName() ).append( "(" ).append( fileTag( current ) ).append( ") | " ). - append( backup.getName() ).append( "(" ).append( fileTag( backup ) ). - append( ") )}" ); + append( original.getName() ).append( "(" ).append( originalIdentity ).append( "->" ).append( fileTag( original ) ).append( ") | " ). + append( current.getName() ).append( "(" ).append( fileTag( current ) ).append( ") | " ). + append( backup.getName() ).append( "(" ).append( fileTag( backup ) ). + append( ") )}" ); return sb.toString(); } void copyOriginalToCurrent() { - if ( original.exists() ) { + if( original.exists() ) + { copy( original, current ); } } void apply() - throws ConcurrentUoWFileStateModificationException + throws ConcurrentUoWFileStateModificationException { LOGGER.trace( "Will apply changes to {}", this ); - if ( fileTag( current ) != originalIdentity ) { - if ( fileTag( original ) != originalIdentity ) { + if( fileTag( current ) != originalIdentity ) + { + if( fileTag( original ) != originalIdentity ) + { LOGGER.info( "Concurrent modification, original creation identity is {} and original apply identity is {}", originalIdentity, fileTag( original ) ); throw new ConcurrentUoWFileStateModificationException( this ); } - if ( original.exists() ) { + if( original.exists() ) + { move( original, backup ); } - if ( current.exists() ) { + if( current.exists() ) + { move( current, original ); } LOGGER.debug( "Applied changes to {}", original ); @@ -87,8 +95,10 @@ public class UoWFile void rollback() { - if ( backup.exists() ) { - if ( fileTag( original ) != originalIdentity ) { + if( backup.exists() ) + { + if( fileTag( original ) != originalIdentity ) + { delete( original ); move( backup, original ); } @@ -98,10 +108,12 @@ public class UoWFile void cleanup() { - if ( current.exists() ) { + if( current.exists() ) + { delete( current ); } - if ( backup.exists() ) { + if( backup.exists() ) + { delete( backup ); } } @@ -116,16 +128,20 @@ public class UoWFile private void copy( File source, File dest ) { - try { + try + { Inputs.byteBuffer( source, FILE_BUFFER_SIZE ).transferTo( Outputs.byteBuffer( dest ) ); - } catch ( IOException ex ) { + } + catch( IOException ex ) + { throw new UoWFileException( ex ); } } private void delete( File file ) { - if ( !file.delete() ) { + if( !file.delete() ) + { throw new UoWFileException( new IOException( "Unable to delete file " + file ) ); } } @@ -133,10 +149,12 @@ public class UoWFile private void move( File source, File dest ) { // Atomic move attempt - if ( !source.renameTo( dest ) ) { + if( !source.renameTo( dest ) ) + { // source and dest are probably on different filesystem, fallback to a non atomic copy/move operation copy( source, dest ); - if ( !source.delete() ) { + if( !source.delete() ) + { throw new UoWFileException( new IOException( "Unable to delete source file " + source + " after copy(move) to " + dest + " (rename failed before that)." ) ); http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFileException.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFileException.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFileException.java index ee9900f..ee48c49 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFileException.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFileException.java @@ -1,24 +1,27 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.internal; import java.io.IOException; class UoWFileException - extends RuntimeException + extends RuntimeException { - UoWFileException( IOException cause ) { super( cause.getMessage(), cause ); @@ -28,5 +31,4 @@ class UoWFileException { super( message, cause ); } - } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFileFactory.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFileFactory.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFileFactory.java index b6ab5db..863a102 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFileFactory.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/internal/UoWFileFactory.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.internal; @@ -18,15 +22,13 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.qi4j.api.activation.ActivatorAdapter; -import org.qi4j.api.activation.Activators; import org.qi4j.api.common.Optional; import org.qi4j.api.injection.scope.Service; import org.qi4j.api.injection.scope.Structure; import org.qi4j.api.injection.scope.This; import org.qi4j.api.mixin.Mixins; +import org.qi4j.api.service.ServiceActivation; import org.qi4j.api.service.ServiceComposite; -import org.qi4j.api.service.ServiceReference; import org.qi4j.api.structure.Application; import org.qi4j.api.structure.Module; import org.qi4j.api.unitofwork.UnitOfWork; @@ -37,35 +39,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Mixins( UoWFileFactory.Mixin.class ) -@Activators( UoWFileFactory.Activator.class ) public interface UoWFileFactory - extends ServiceComposite + extends ServiceActivation { UoWFile createCurrentUoWFile( File file ); - void ensureWorkDirsExist() - throws IOException; - - class Activator - extends ActivatorAdapter<ServiceReference<UoWFileFactory>> - { - - @Override - public void afterActivation( ServiceReference<UoWFileFactory> activated ) - throws Exception - { - activated.get().ensureWorkDirsExist(); - } - - } - - abstract class Mixin - implements UoWFileFactory + class Mixin + implements UoWFileFactory { private static class UoWFilesMetaInfo - extends HashMap<String, UoWFile> + extends HashMap<String, UoWFile> { } @@ -87,22 +72,32 @@ public interface UoWFileFactory private File workDir; @Override - public void ensureWorkDirsExist() - throws IOException + public void activateService() + throws IOException { File tmp; - if ( fileConfig == null ) { + if( fileConfig == null ) + { tmp = new File( "qi4j", app.name() + "-" + app.version() ); - } else { + } + else + { tmp = fileConfig.temporaryDirectory(); } workDir = new File( tmp, "uowfile-" + me.identity().get() ); - if ( !workDir.exists() && !workDir.mkdirs() ) { + if( !workDir.exists() && !workDir.mkdirs() ) + { throw new IOException( "Unable to create temporary directory: " + workDir ); } } @Override + public void passivateService() + throws Exception + { + } + + @Override public UoWFile createCurrentUoWFile( File file ) { return createUoWFile( module.currentUnitOfWork(), file, workDir ); @@ -113,7 +108,8 @@ public interface UoWFileFactory UoWFilesMetaInfo uowMeta = ensureUoWMeta( uow ); String absolutePath = file.getAbsolutePath(); UoWFile uowFile = uowMeta.get( absolutePath ); - if ( uowFile == null ) { + if( uowFile == null ) + { uowFile = new UoWFile( file, workDir ); uowFile.copyOriginalToCurrent(); uowMeta.put( absolutePath, uowFile ); @@ -128,7 +124,8 @@ public interface UoWFileFactory private static UoWFilesMetaInfo ensureUoWMeta( final UnitOfWork uow ) { UoWFilesMetaInfo uowMeta = uow.metaInfo( UoWFilesMetaInfo.class ); - if ( uowMeta != null ) { + if( uowMeta != null ) + { return uowMeta; } @@ -137,22 +134,27 @@ public interface UoWFileFactory uow.addUnitOfWorkCallback( new UnitOfWorkCallback() { - @Override public void beforeCompletion() - throws UnitOfWorkCompletionException + throws UnitOfWorkCompletionException { UoWFilesMetaInfo uowMeta = uow.metaInfo( UoWFilesMetaInfo.class ); - if ( uowMeta != null && !uowMeta.isEmpty() ) { - List<UoWFile> concurrentlyModified = new ArrayList<UoWFile>(); - for ( UoWFile eachUoWFile : uowMeta.values() ) { - try { + if( uowMeta != null && !uowMeta.isEmpty() ) + { + List<UoWFile> concurrentlyModified = new ArrayList<>(); + for( UoWFile eachUoWFile : uowMeta.values() ) + { + try + { eachUoWFile.apply(); - } catch ( ConcurrentUoWFileStateModificationException ex ) { + } + catch( ConcurrentUoWFileStateModificationException ex ) + { concurrentlyModified.add( ex.getUoWFile() ); } } - if ( !concurrentlyModified.isEmpty() ) { + if( !concurrentlyModified.isEmpty() ) + { throw new ConcurrentUoWFileModificationException( concurrentlyModified ); } } @@ -162,9 +164,12 @@ public interface UoWFileFactory public void afterCompletion( UnitOfWorkStatus status ) { UoWFilesMetaInfo uowMeta = uow.metaInfo( UoWFilesMetaInfo.class ); - if ( uowMeta != null && !uowMeta.isEmpty() ) { - for ( UoWFile eachUoWFile : uowMeta.values() ) { - if ( status == UnitOfWorkStatus.DISCARDED ) { + if( uowMeta != null && !uowMeta.isEmpty() ) + { + for( UoWFile eachUoWFile : uowMeta.values() ) + { + if( status == UnitOfWorkStatus.DISCARDED ) + { eachUoWFile.rollback(); } eachUoWFile.cleanup(); @@ -172,11 +177,9 @@ public interface UoWFileFactory uow.metaInfo( UoWFilesMetaInfo.class ).clear(); } } - } ); return uowMeta; } - } } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/HasUoWFiles.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/HasUoWFiles.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/HasUoWFiles.java index 44f8766..f1d2ac1 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/HasUoWFiles.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/HasUoWFiles.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.plural; @@ -26,7 +30,6 @@ import org.qi4j.library.uowfile.internal.UoWFileFactory; // START SNIPPET: contract public interface HasUoWFiles<T extends Enum<T>> { - /** * IMPORTANT Use this {@link File} only inside read-only {@link UnitOfWork}s */ @@ -43,9 +46,8 @@ public interface HasUoWFiles<T extends Enum<T>> // END SNIPPET: contract abstract class Mixin<R extends Enum<R>> - implements HasUoWFiles<R> + implements HasUoWFiles<R> { - @Service private UoWFileFactory uowFileFactory; @This @@ -72,13 +74,13 @@ public interface HasUoWFiles<T extends Enum<T>> @Override public Iterable<File> managedFiles() { - List<File> managedFiles = new ArrayList<File>(); - for ( File eachAttachedFile : locator.locateAttachedFiles() ) { + List<File> managedFiles = new ArrayList<>(); + for( File eachAttachedFile : locator.locateAttachedFiles() ) + { managedFiles.add( uowFileFactory.createCurrentUoWFile( eachAttachedFile ).asFile() ); } return managedFiles; } - } // START SNIPPET: contract http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/HasUoWFilesLifecycle.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/HasUoWFilesLifecycle.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/HasUoWFilesLifecycle.java index 06d88c3..5a634f6 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/HasUoWFilesLifecycle.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/HasUoWFilesLifecycle.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.plural; @@ -23,41 +27,42 @@ import org.qi4j.api.mixin.Mixins; @Mixins( HasUoWFilesLifecycle.Mixin.class ) public interface HasUoWFilesLifecycle<T extends Enum<T>> - extends HasUoWFiles<T>, Lifecycle + extends HasUoWFiles<T>, Lifecycle { - public class Mixin - implements Lifecycle + implements Lifecycle { - @This private HasUoWFiles<?> hasUoWFiles; @Override public void create() - throws LifecycleException + throws LifecycleException { // NOOP } @Override public void remove() - throws LifecycleException + throws LifecycleException { // We use the managed files so that if the UoW gets discarded the files will be restored - List<File> errors = new ArrayList<File>(); - for ( File eachFile : hasUoWFiles.managedFiles() ) { - if ( eachFile.exists() ) { - if ( !eachFile.delete() ) { + List<File> errors = new ArrayList<>(); + for( File eachFile : hasUoWFiles.managedFiles() ) + { + if( eachFile.exists() ) + { + if( !eachFile.delete() ) + { errors.add( eachFile ); } } } - if ( !errors.isEmpty() ) { + if( !errors.isEmpty() ) + { throw new LifecycleException( "Unable to delete existing files: " + errors ); } } - } } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/UoWFilesLocator.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/UoWFilesLocator.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/UoWFilesLocator.java index 5b634fb..11e9263 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/UoWFilesLocator.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/plural/UoWFilesLocator.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.plural; @@ -17,9 +21,7 @@ import java.io.File; public interface UoWFilesLocator<T extends Enum<T>> { - File locateAttachedFile( T key ); Iterable<File> locateAttachedFiles(); - } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/HasUoWFile.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/HasUoWFile.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/HasUoWFile.java index 5316e41..074312c 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/HasUoWFile.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/HasUoWFile.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.singular; @@ -24,9 +28,8 @@ import org.qi4j.library.uowfile.internal.UoWFileFactory; // START SNIPPET: contract public interface HasUoWFile { - /** - * IMPORTANT Use this {@link File} only inside read-only {@link UnitOfWork}s + * IMPORTANT Use this {@link File} inside read-only {@link UnitOfWork}s only */ File attachedFile(); @@ -34,9 +37,8 @@ public interface HasUoWFile // END SNIPPET: contract class Mixin - implements HasUoWFile + implements HasUoWFile { - @Service private UoWFileFactory uowFileFactory; @@ -54,8 +56,8 @@ public interface HasUoWFile { return uowFileFactory.createCurrentUoWFile( locator.locateAttachedFile() ).asFile(); } - } // START SNIPPET: contract + } // END SNIPPET: contract http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/HasUoWFileLifecycle.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/HasUoWFileLifecycle.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/HasUoWFileLifecycle.java index 31794b6..83364de 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/HasUoWFileLifecycle.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/HasUoWFileLifecycle.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.singular; @@ -21,34 +25,32 @@ import org.qi4j.api.mixin.Mixins; @Mixins( HasUoWFileLifecycle.Mixin.class ) public interface HasUoWFileLifecycle - extends HasUoWFile, Lifecycle + extends HasUoWFile, Lifecycle { - class Mixin - implements Lifecycle + implements Lifecycle { - @This private HasUoWFile hasUoWFile; @Override public void create() - throws LifecycleException + throws LifecycleException { // NOOP } @Override public void remove() - throws LifecycleException + throws LifecycleException { // We use the managed file so that if the UoW gets discarded the file will be restored File file = hasUoWFile.managedFile(); - if ( file.exists() && !file.delete() ) { + if( file.exists() && !file.delete() ) + { throw new LifecycleException( "Unable to delete existing file: " + file ); } } - } } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/UoWFileLocator.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/UoWFileLocator.java b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/UoWFileLocator.java index 3cabd0f..7555c04 100644 --- a/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/UoWFileLocator.java +++ b/libraries/uowfile/src/main/java/org/qi4j/library/uowfile/singular/UoWFileLocator.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile.singular; @@ -17,7 +21,5 @@ import java.io.File; public interface UoWFileLocator { - File locateAttachedFile(); - } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/AbstractUoWFileTest.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/AbstractUoWFileTest.java b/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/AbstractUoWFileTest.java index f25edf0..8250658 100644 --- a/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/AbstractUoWFileTest.java +++ b/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/AbstractUoWFileTest.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011-2014 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile; @@ -18,27 +22,26 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Stack; - import org.junit.AfterClass; import org.junit.BeforeClass; - import org.qi4j.io.Inputs; import org.qi4j.io.Outputs; import org.qi4j.test.AbstractQi4jTest; public abstract class AbstractUoWFileTest - extends AbstractQi4jTest + extends AbstractQi4jTest { - protected static File baseTestDir; @BeforeClass public static void beforeClass() - throws IOException + throws IOException { - File testDir = new File( "build/uowfiletest"); - if ( !testDir.exists() ) { - if ( !testDir.mkdirs() ) { + File testDir = new File( "build/uowfiletest" ); + if( !testDir.exists() ) + { + if( !testDir.mkdirs() ) + { throw new IOException( "Unable to create directory: " + testDir ); } } @@ -49,32 +52,39 @@ public abstract class AbstractUoWFileTest public static void afterClass() { // Delete test data - Stack<File> stack = new Stack<File>(); + Stack<File> stack = new Stack<>(); stack.push( baseTestDir ); - while ( !stack.empty() ) { + while( !stack.empty() ) + { File each = stack.peek(); - if ( each.isDirectory() ) { + if( each.isDirectory() ) + { File[] children = each.listFiles(); - if ( children.length > 0 ) { - for ( File child : children ) { + if( children.length > 0 ) + { + for( File child : children ) + { stack.push( child ); } - } else { + } + else + { stack.pop().delete(); } - } else { + } + else + { stack.pop().delete(); } } } protected final boolean isFileFirstLineEqualsTo( File file, String start ) - throws IOException + throws IOException { - List<String> lines = new ArrayList<String>(); + List<String> lines = new ArrayList<>(); // This load the full file but used test resources are single line files Inputs.text( file ).transferTo( Outputs.collection( lines ) ); return lines.get( 0 ).trim().startsWith( start ); } - } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/HasUoWFileTest.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/HasUoWFileTest.java b/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/HasUoWFileTest.java index 811ed03..c7de8d2 100644 --- a/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/HasUoWFileTest.java +++ b/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/HasUoWFileTest.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011-2014 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile; @@ -18,20 +22,15 @@ import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.List; - -import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; - import org.qi4j.api.concern.Concerns; import org.qi4j.api.entity.EntityBuilder; -import org.qi4j.api.entity.EntityComposite; import org.qi4j.api.entity.Identity; import org.qi4j.api.injection.scope.Structure; import org.qi4j.api.injection.scope.This; import org.qi4j.api.mixin.Mixins; import org.qi4j.api.property.Property; -import org.qi4j.api.service.ServiceComposite; import org.qi4j.api.structure.Module; import org.qi4j.api.unitofwork.UnitOfWork; import org.qi4j.api.unitofwork.UnitOfWorkCompletionException; @@ -47,40 +46,36 @@ import org.qi4j.library.uowfile.internal.ConcurrentUoWFileModificationException; import org.qi4j.library.uowfile.singular.HasUoWFileLifecycle; import org.qi4j.library.uowfile.singular.UoWFileLocator; import org.qi4j.test.EntityTestAssembler; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + public class HasUoWFileTest - extends AbstractUoWFileTest + extends AbstractUoWFileTest { - private static final Logger LOGGER = LoggerFactory.getLogger( HasUoWFileTest.class ); - private static final URL CREATION_CONTENT_URL = HasUoWFileTest.class.getResource( "creation.txt" ); - private static final URL MODIFICATION_CONTENT_URL = HasUoWFileTest.class.getResource( "modification.txt" ); // START SNIPPET: entity // START SNIPPET: uowfile public interface TestedEntity - extends EntityComposite, - // END SNIPPET: entity - HasUoWFileLifecycle + extends HasUoWFileLifecycle // END SNIPPET: entity + , Identity // START SNIPPET: entity { - Property<String> name(); - } // END SNIPPET: entity // END SNIPPET: uowfile // START SNIPPET: locator - public static abstract class TestedFileLocatorMixin - implements UoWFileLocator + public static class TestedFileLocatorMixin + implements UoWFileLocator { - @This private Identity meAsIdentity; @@ -89,65 +84,68 @@ public class HasUoWFileTest { return new File( baseTestDir, meAsIdentity.identity().get() ); } - } // END SNIPPET: locator @Mixins( HasUoWFileTest.TestServiceMixin.class ) @Concerns( UnitOfWorkConcern.class ) public interface TestService - extends ServiceComposite { - void modifyFile( String entityId ) - throws IOException; + throws IOException; @UnitOfWorkPropagation @UnitOfWorkRetry void modifyFileWithRetry( String entityId, long sleepBefore, long sleepAfter ) - throws IOException; - + throws IOException; } public static abstract class TestServiceMixin - implements TestService + implements TestService { - @Structure private Module module; @Override public void modifyFile( String entityId ) - throws IOException + throws IOException { modifyFileImmediatly( entityId ); } @Override public void modifyFileWithRetry( String entityId, long sleepBefore, long sleepAfter ) - throws IOException + throws IOException { LOGGER.info( "Waiting " + sleepBefore + "ms before file modification" ); - if ( sleepBefore > 0 ) { - try { + if( sleepBefore > 0 ) + { + try + { Thread.sleep( sleepBefore ); - } catch ( InterruptedException ex ) { + } + catch( InterruptedException ex ) + { throw new RuntimeException( ex ); } } modifyFileImmediatly( entityId ); LOGGER.info( "Waiting " + sleepAfter + "ms after file modification" ); - if ( sleepAfter > 0 ) { - try { + if( sleepAfter > 0 ) + { + try + { Thread.sleep( sleepAfter ); - } catch ( InterruptedException ex ) { + } + catch( InterruptedException ex ) + { throw new RuntimeException( ex ); } } } private void modifyFileImmediatly( String entityId ) - throws IOException + throws IOException { TestedEntity entity = module.currentUnitOfWork().get( TestedEntity.class, entityId ); // START SNIPPET: api @@ -162,7 +160,7 @@ public class HasUoWFileTest @Override // START SNIPPET: assembly public void assemble( ModuleAssembly module ) - throws AssemblyException + throws AssemblyException { new UoWFileAssembler().assemble( module ); @@ -184,148 +182,183 @@ public class HasUoWFileTest @Test public void testCreation() - throws UnitOfWorkCompletionException, IOException + throws UnitOfWorkCompletionException, IOException { LOGGER.info( "# Test Creation ##############################################################################" ); + File attachedFile; // Test discarded creation - UnitOfWork uow = module.newUnitOfWork(); - TestedEntity entity = createTestedEntity( uow, "Testing Creation Rollback" ); - File attachedFile = entity.attachedFile(); - uow.discard(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedEntity( uow, "Testing Creation Rollback" ); + attachedFile = entity.attachedFile(); + } assertFalse( "File still exists after discarded creation UoW", attachedFile.exists() ); // Test completed creation - uow = module.newUnitOfWork(); - entity = createTestedEntity( uow, "Testing Creation" ); - attachedFile = entity.attachedFile(); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedEntity( uow, "Testing Creation" ); + attachedFile = entity.attachedFile(); + uow.complete(); + } assertTrue( "File content was not the good one", isFileFirstLineEqualsTo( attachedFile, "Creation" ) ); } @Test public void testModification() - throws UnitOfWorkCompletionException, IOException + throws UnitOfWorkCompletionException, IOException { LOGGER.info( "# Test Modification ##########################################################################" ); + final String entityId; + File attachedFile; // Create new - UnitOfWork uow = module.newUnitOfWork(); - TestedEntity entity = createTestedEntity( uow, "Testing Modification" ); - String entityId = entity.identity().get(); - File attachedFile = entity.attachedFile(); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedEntity( uow, "Testing Modification" ); + entityId = entity.identity().get(); + attachedFile = entity.attachedFile(); + uow.complete(); + } // Testing discarded modification - uow = module.newUnitOfWork(); - testService.modifyFile( entityId ); - uow.discard(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + testService.modifyFile( entityId ); + } assertTrue( "File content after discarded modification was not the good one", isFileFirstLineEqualsTo( attachedFile, "Creation" ) ); // Testing completed modification - uow = module.newUnitOfWork(); - testService.modifyFile( entityId ); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + testService.modifyFile( entityId ); + uow.complete(); + } assertTrue( "Modified file content was not the good one", isFileFirstLineEqualsTo( attachedFile, "Modification" ) ); } @Test public void testDeletion() - throws UnitOfWorkCompletionException, IOException + throws UnitOfWorkCompletionException, IOException { LOGGER.info( "# Test Deletion ##############################################################################" ); + final String entityId; + File attachedFile; // Create new - UnitOfWork uow = module.newUnitOfWork(); - TestedEntity entity = createTestedEntity( uow, "Testing Deletion" ); - String entityId = entity.identity().get(); - File attachedFile = entity.attachedFile(); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedEntity( uow, "Testing Deletion" ); + entityId = entity.identity().get(); + attachedFile = entity.attachedFile(); + uow.complete(); + } // Testing discarded deletion - uow = module.newUnitOfWork(); - entity = uow.get( TestedEntity.class, entityId ); - uow.remove( entity ); - uow.discard(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = uow.get( TestedEntity.class, entityId ); + uow.remove( entity ); + } assertTrue( "File do not exists after discarded deletion", attachedFile.exists() ); // Testing completed deletion - uow = module.newUnitOfWork(); - entity = uow.get( TestedEntity.class, entityId ); - uow.remove( entity ); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = uow.get( TestedEntity.class, entityId ); + uow.remove( entity ); + uow.complete(); + } assertFalse( "File still exists after deletion", attachedFile.exists() ); } @Test public void testConcurrentModification() - throws IOException, UnitOfWorkCompletionException + throws IOException, UnitOfWorkCompletionException { LOGGER.info( "# Test Concurrent Modification ###############################################################" ); + final String entityId; // Create new - UnitOfWork uow = module.newUnitOfWork(); - TestedEntity entity = createTestedEntity( uow, "Testing Concurrent Modification" ); - String entityId = entity.identity().get(); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedEntity( uow, "Testing Concurrent Modification" ); + entityId = entity.identity().get(); + uow.complete(); + } // Testing concurrent modification + UnitOfWork uow, uow2; + TestedEntity entity; + uow = module.newUnitOfWork(); entity = uow.get( TestedEntity.class, entityId ); Inputs.text( MODIFICATION_CONTENT_URL ).transferTo( Outputs.text( entity.managedFile() ) ); - UnitOfWork uow2 = module.newUnitOfWork(); + + uow2 = module.newUnitOfWork(); entity = uow2.get( TestedEntity.class, entityId ); Inputs.text( MODIFICATION_CONTENT_URL ).transferTo( Outputs.text( entity.managedFile() ) ); + uow.complete(); - try { + try + { uow2.complete(); fail( "A ConcurrentUoWFileModificationException should have been raised" ); - } catch ( ConcurrentUoWFileModificationException expected ) { + } + catch( ConcurrentUoWFileModificationException expected ) + { uow2.discard(); } } @Test public void testRetry() - throws IOException, UnitOfWorkCompletionException, InterruptedException + throws IOException, UnitOfWorkCompletionException, InterruptedException { LOGGER.info( "# Test Retry #################################################################################" ); + final String entityId; + File attachedFile; // Create new - UnitOfWork uow = module.newUnitOfWork(); - TestedEntity entity = createTestedEntity( uow, "Testing Concurrent Modification" ); - final String entityId = entity.identity().get(); - File attachedFile = entity.attachedFile(); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedEntity( uow, "Testing Concurrent Modification" ); + entityId = entity.identity().get(); + attachedFile = entity.attachedFile(); + uow.complete(); + } - final List<Exception> ex = new ArrayList<Exception>(); + final List<Exception> ex = new ArrayList<>(); Thread t1 = new Thread( new Runnable() { - @Override public void run() { - try { + try + { testService.modifyFileWithRetry( entityId, 0, 3000 ); - } catch ( Exception ex1 ) { + } + catch( Exception ex1 ) + { ex.add( ex1 ); } } - }, "job1" ); Thread t2 = new Thread( new Runnable() { - @Override public void run() { - try { + try + { testService.modifyFileWithRetry( entityId, 1000, 0 ); - } catch ( Exception ex1 ) { + } + catch( Exception ex1 ) + { ex.add( ex1 ); } } - }, "job2" ); t1.start(); @@ -334,7 +367,8 @@ public class HasUoWFileTest t1.join(); t2.join(); - for ( Exception eachEx : ex ) { + for( Exception eachEx : ex ) + { eachEx.printStackTrace(); } @@ -343,7 +377,7 @@ public class HasUoWFileTest } private TestedEntity createTestedEntity( UnitOfWork uow, String name ) - throws IOException + throws IOException { EntityBuilder<TestedEntity> builder = uow.newEntityBuilder( TestedEntity.class ); TestedEntity entity = builder.instance(); http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/b049e9b6/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/HasUoWFilesTest.java ---------------------------------------------------------------------- diff --git a/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/HasUoWFilesTest.java b/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/HasUoWFilesTest.java index a358ec7..8ecd1ab 100644 --- a/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/HasUoWFilesTest.java +++ b/libraries/uowfile/src/test/java/org/qi4j/library/uowfile/HasUoWFilesTest.java @@ -1,15 +1,19 @@ /* - * Copyright (c) 2011, Paul Merlin. All Rights Reserved. + * Copyright 2011-2014 Paul Merlin. + * + * 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 * - * 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. + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * * See the License for the specific language governing permissions and * limitations under the License. - * */ package org.qi4j.library.uowfile; @@ -18,20 +22,15 @@ import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.List; - -import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; - import org.qi4j.api.concern.Concerns; import org.qi4j.api.entity.EntityBuilder; -import org.qi4j.api.entity.EntityComposite; import org.qi4j.api.entity.Identity; import org.qi4j.api.injection.scope.Structure; import org.qi4j.api.injection.scope.This; import org.qi4j.api.mixin.Mixins; import org.qi4j.api.property.Property; -import org.qi4j.api.service.ServiceComposite; import org.qi4j.api.structure.Module; import org.qi4j.api.unitofwork.UnitOfWork; import org.qi4j.api.unitofwork.UnitOfWorkCompletionException; @@ -47,55 +46,50 @@ import org.qi4j.library.uowfile.internal.ConcurrentUoWFileModificationException; import org.qi4j.library.uowfile.plural.HasUoWFilesLifecycle; import org.qi4j.library.uowfile.plural.UoWFilesLocator; import org.qi4j.test.EntityTestAssembler; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + public class HasUoWFilesTest - extends AbstractUoWFileTest + extends AbstractUoWFileTest { - private static final Logger LOGGER = LoggerFactory.getLogger( HasUoWFilesTest.class ); - private static final URL CREATION_CONTENT_URL = HasUoWFilesTest.class.getResource( "creation.txt" ); - private static final URL MODIFICATION_CONTENT_URL = HasUoWFilesTest.class.getResource( "modification.txt" ); // START SNIPPET: uowfile public enum MyEnum { - fileOne, fileTwo - } // START SNIPPET: entity public interface TestedEntity - extends EntityComposite, - // END SNIPPET: entity - HasUoWFilesLifecycle<MyEnum> + extends HasUoWFilesLifecycle<MyEnum> // END SNIPPET: entity + , Identity // START SNIPPET: entity { - Property<String> name(); - } // END SNIPPET: entity // END SNIPPET: uowfile // START SNIPPET: locator public static abstract class TestedFilesLocatorMixin - implements UoWFilesLocator<MyEnum> + implements UoWFilesLocator<MyEnum> { - @This private Identity meAsIdentity; @Override public Iterable<File> locateAttachedFiles() { - List<File> list = new ArrayList<File>(); - for ( MyEnum eachValue : MyEnum.values() ) { + List<File> list = new ArrayList<>(); + for( MyEnum eachValue : MyEnum.values() ) + { list.add( new File( baseTestDir, meAsIdentity.identity().get() + "." + eachValue.name() ) ); } return list; @@ -106,65 +100,68 @@ public class HasUoWFilesTest { return new File( baseTestDir, meAsIdentity.identity().get() + "." + key.name() ); } - } // END SNIPPET: locator @Mixins( TestServiceMixin.class ) @Concerns( UnitOfWorkConcern.class ) public interface TestService - extends ServiceComposite { - void modifyFile( String entityId ) - throws IOException; + throws IOException; @UnitOfWorkPropagation @UnitOfWorkRetry void modifyFileWithRetry( String entityId, long sleepBefore, long sleepAfter ) - throws IOException; - + throws IOException; } - public static abstract class TestServiceMixin - implements TestService + public static class TestServiceMixin + implements TestService { - @Structure private Module module; @Override public void modifyFile( String entityId ) - throws IOException + throws IOException { modifyFileImmediatly( entityId ); } @Override public void modifyFileWithRetry( String entityId, long sleepBefore, long sleepAfter ) - throws IOException + throws IOException { LOGGER.info( "Waiting " + sleepBefore + "ms before file modification" ); - if ( sleepBefore > 0 ) { - try { + if( sleepBefore > 0 ) + { + try + { Thread.sleep( sleepBefore ); - } catch ( InterruptedException ex ) { + } + catch( InterruptedException ex ) + { throw new RuntimeException( ex ); } } modifyFileImmediatly( entityId ); LOGGER.info( "Waiting " + sleepAfter + "ms after file modification" ); - if ( sleepAfter > 0 ) { - try { + if( sleepAfter > 0 ) + { + try + { Thread.sleep( sleepAfter ); - } catch ( InterruptedException ex ) { + } + catch( InterruptedException ex ) + { throw new RuntimeException( ex ); } } } private void modifyFileImmediatly( String entityId ) - throws IOException + throws IOException { TestedEntity entity = module.currentUnitOfWork().get( TestedEntity.class, entityId ); // START SNIPPET: api @@ -173,13 +170,12 @@ public class HasUoWFilesTest // END SNIPPET: api Inputs.text( MODIFICATION_CONTENT_URL ).transferTo( Outputs.text( managedFileOne ) ); } - } @Override // START SNIPPET: assembly public void assemble( ModuleAssembly module ) - throws AssemblyException + throws AssemblyException { new UoWFileAssembler().assemble( module ); @@ -201,148 +197,183 @@ public class HasUoWFilesTest @Test public void testCreation() - throws UnitOfWorkCompletionException, IOException + throws UnitOfWorkCompletionException, IOException { LOGGER.info( "# Test Creation ##############################################################################" ); + File attachedFile; // Test discarded creation - UnitOfWork uow = module.newUnitOfWork(); - TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Creation Rollback" ); - File attachedFile = entity.attachedFile( MyEnum.fileOne ); - uow.discard(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Creation Rollback" ); + attachedFile = entity.attachedFile( MyEnum.fileOne ); + } assertFalse( "File still exists after discarded creation UoW", attachedFile.exists() ); // Test completed creation - uow = module.newUnitOfWork(); - entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Creation" ); - attachedFile = entity.attachedFile( MyEnum.fileOne ); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Creation" ); + attachedFile = entity.attachedFile( MyEnum.fileOne ); + uow.complete(); + } assertTrue( "File content was not the good one", isFileFirstLineEqualsTo( attachedFile, "Creation" ) ); } @Test public void testModification() - throws UnitOfWorkCompletionException, IOException + throws UnitOfWorkCompletionException, IOException { LOGGER.info( "# Test Modification ##########################################################################" ); + final String entityId; + File attachedFile; // Create new - UnitOfWork uow = module.newUnitOfWork(); - TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Modification" ); - String entityId = entity.identity().get(); - File attachedFile = entity.attachedFile( MyEnum.fileOne ); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Modification" ); + entityId = entity.identity().get(); + attachedFile = entity.attachedFile( MyEnum.fileOne ); + uow.complete(); + } // Testing discarded modification - uow = module.newUnitOfWork(); - testService.modifyFile( entityId ); - uow.discard(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + testService.modifyFile( entityId ); + } assertTrue( "File content after discarded modification was not the good one", isFileFirstLineEqualsTo( attachedFile, "Creation" ) ); // Testing completed modification - uow = module.newUnitOfWork(); - testService.modifyFile( entityId ); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + testService.modifyFile( entityId ); + uow.complete(); + } assertTrue( "Modified file content was not the good one", isFileFirstLineEqualsTo( attachedFile, "Modification" ) ); } @Test public void testDeletion() - throws UnitOfWorkCompletionException, IOException + throws UnitOfWorkCompletionException, IOException { LOGGER.info( "# Test Deletion ##############################################################################" ); + final String entityId; + File attachedFile; // Create new - UnitOfWork uow = module.newUnitOfWork(); - TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Deletion" ); - String entityId = entity.identity().get(); - File attachedFile = entity.attachedFile( MyEnum.fileOne ); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Deletion" ); + entityId = entity.identity().get(); + attachedFile = entity.attachedFile( MyEnum.fileOne ); + uow.complete(); + } // Testing discarded deletion - uow = module.newUnitOfWork(); - entity = uow.get( TestedEntity.class, entityId ); - uow.remove( entity ); - uow.discard(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = uow.get( TestedEntity.class, entityId ); + uow.remove( entity ); + } assertTrue( "File do not exists after discarded deletion", attachedFile.exists() ); // Testing completed deletion - uow = module.newUnitOfWork(); - entity = uow.get( TestedEntity.class, entityId ); - uow.remove( entity ); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = uow.get( TestedEntity.class, entityId ); + uow.remove( entity ); + uow.complete(); + } assertFalse( "File still exists after deletion", attachedFile.exists() ); } @Test public void testConcurrentModification() - throws IOException, UnitOfWorkCompletionException + throws IOException, UnitOfWorkCompletionException { LOGGER.info( "# Test Concurrent Modification ###############################################################" ); + final String entityId; // Create new - UnitOfWork uow = module.newUnitOfWork(); - TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Concurrent Modification" ); - String entityId = entity.identity().get(); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Concurrent Modification" ); + entityId = entity.identity().get(); + uow.complete(); + } // Testing concurrent modification + UnitOfWork uow, uow2; + TestedEntity entity; + uow = module.newUnitOfWork(); entity = uow.get( TestedEntity.class, entityId ); Inputs.text( MODIFICATION_CONTENT_URL ).transferTo( Outputs.text( entity.managedFile( MyEnum.fileOne ) ) ); - UnitOfWork uow2 = module.newUnitOfWork(); + + uow2 = module.newUnitOfWork(); entity = uow2.get( TestedEntity.class, entityId ); Inputs.text( MODIFICATION_CONTENT_URL ).transferTo( Outputs.text( entity.managedFile( MyEnum.fileOne ) ) ); + uow.complete(); - try { + try + { uow2.complete(); fail( "A ConcurrentUoWFileModificationException should have been raised" ); - } catch ( ConcurrentUoWFileModificationException expected ) { + } + catch( ConcurrentUoWFileModificationException expected ) + { uow2.discard(); } } @Test public void testRetry() - throws IOException, UnitOfWorkCompletionException, InterruptedException + throws IOException, UnitOfWorkCompletionException, InterruptedException { LOGGER.info( "# Test Retry #################################################################################" ); + final String entityId; + File attachedFile; // Create new - UnitOfWork uow = module.newUnitOfWork(); - TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Concurrent Modification" ); - final String entityId = entity.identity().get(); - File attachedFile = entity.attachedFile( MyEnum.fileOne ); - uow.complete(); + try( UnitOfWork uow = module.newUnitOfWork() ) + { + TestedEntity entity = createTestedOneEntityTwoFilesEntity( uow, "Testing Concurrent Modification" ); + entityId = entity.identity().get(); + attachedFile = entity.attachedFile( MyEnum.fileOne ); + uow.complete(); + } - final List<Exception> ex = new ArrayList<Exception>(); + final List<Exception> ex = new ArrayList<>(); Thread t1 = new Thread( new Runnable() { - @Override public void run() { - try { + try + { testService.modifyFileWithRetry( entityId, 0, 10000 ); - } catch ( Exception ex1 ) { + } + catch( Exception ex1 ) + { ex.add( ex1 ); } } - }, "job1" ); Thread t2 = new Thread( new Runnable() { - @Override public void run() { - try { + try + { testService.modifyFileWithRetry( entityId, 5000, 0 ); - } catch ( Exception ex1 ) { + } + catch( Exception ex1 ) + { ex.add( ex1 ); } } - }, "job2" ); t1.start(); @@ -351,7 +382,8 @@ public class HasUoWFilesTest t1.join(); t2.join(); - for ( Exception eachEx : ex ) { + for( Exception eachEx : ex ) + { eachEx.printStackTrace(); } @@ -360,7 +392,7 @@ public class HasUoWFilesTest } private TestedEntity createTestedOneEntityTwoFilesEntity( UnitOfWork uow, String name ) - throws IOException + throws IOException { EntityBuilder<TestedEntity> builder = uow.newEntityBuilder( TestedEntity.class ); TestedEntity entity = builder.instance();
