Return-Path: X-Original-To: apmail-zest-commits-archive@minotaur.apache.org Delivered-To: apmail-zest-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 20F4A184C1 for ; Wed, 8 Jul 2015 08:15:12 +0000 (UTC) Received: (qmail 74405 invoked by uid 500); 8 Jul 2015 08:15:12 -0000 Delivered-To: apmail-zest-commits-archive@zest.apache.org Received: (qmail 74359 invoked by uid 500); 8 Jul 2015 08:15:12 -0000 Mailing-List: contact commits-help@zest.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@zest.apache.org Delivered-To: mailing list commits@zest.apache.org Received: (qmail 74310 invoked by uid 99); 8 Jul 2015 08:15:12 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 08 Jul 2015 08:15:12 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id D54B4E0415; Wed, 8 Jul 2015 08:15:11 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: niclas@apache.org To: commits@zest.apache.org Date: Wed, 08 Jul 2015 08:15:12 -0000 Message-Id: <35c9d61e34dc43389ab593c3859bb838@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [2/6] zest-qi4j git commit: Fix for ZEST-40, unifying the Identity-to-filename encoding. Fix for ZEST-40, unifying the Identity-to-filename encoding. Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/7c48e8a7 Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/7c48e8a7 Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/7c48e8a7 Branch: refs/heads/develop Commit: 7c48e8a7cce8b1c6223038c225c4441cdf42c142 Parents: 8f89de5 Author: Niclas Hedhman Authored: Wed Jul 8 09:38:17 2015 +0300 Committer: Niclas Hedhman Committed: Wed Jul 8 09:38:17 2015 +0300 ---------------------------------------------------------------------- .../file/FileEntityStoreConfiguration.java | 16 ++++- .../entitystore/file/FileEntityStoreMixin.java | 65 ++++++++++++++++---- 2 files changed, 68 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/7c48e8a7/extensions/entitystore-file/src/main/java/org/qi4j/entitystore/file/FileEntityStoreConfiguration.java ---------------------------------------------------------------------- diff --git a/extensions/entitystore-file/src/main/java/org/qi4j/entitystore/file/FileEntityStoreConfiguration.java b/extensions/entitystore-file/src/main/java/org/qi4j/entitystore/file/FileEntityStoreConfiguration.java index 37eefde..4cf490c 100644 --- a/extensions/entitystore-file/src/main/java/org/qi4j/entitystore/file/FileEntityStoreConfiguration.java +++ b/extensions/entitystore-file/src/main/java/org/qi4j/entitystore/file/FileEntityStoreConfiguration.java @@ -34,8 +34,22 @@ public interface FileEntityStoreConfiguration /** * The directory where the File Entity Store will be keep its persisted state. *

- * Default: System.getProperty( "user.dir" ) + "/qi4j/filestore"; + * If no configuration is provided at all, then the default location is + * {@code System.getProperty( "user.dir" ) + "/qi4j/filestore"; }. + * If a configuration is given, the entity store will be placed in the + * DATA directory, which is operating system specific. *

+ * + * + * + * + * + *
OSLocation
Linux/Unix{user}/.{application}/data
OSX{user}/Library/Application Support/{application}
Windows{user}/Application Data/{application}/data
+ *

+     * where;
+     *   {user} = Current User's home directory
+     *   {application} = Application's name, as set in assembly.
+     * 
*

* Ignored if the FileConfiguration service is found. *

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/7c48e8a7/extensions/entitystore-file/src/main/java/org/qi4j/entitystore/file/FileEntityStoreMixin.java ---------------------------------------------------------------------- diff --git a/extensions/entitystore-file/src/main/java/org/qi4j/entitystore/file/FileEntityStoreMixin.java b/extensions/entitystore-file/src/main/java/org/qi4j/entitystore/file/FileEntityStoreMixin.java index 2151e98..fa71ea7 100644 --- a/extensions/entitystore-file/src/main/java/org/qi4j/entitystore/file/FileEntityStoreMixin.java +++ b/extensions/entitystore-file/src/main/java/org/qi4j/entitystore/file/FileEntityStoreMixin.java @@ -74,17 +74,15 @@ public class FileEntityStoreMixin { if( fileConfiguration != null ) { - pathName = new File( fileConfiguration.dataDirectory(), config.get() - .identity() - .get() ).getAbsolutePath(); + String storeId = config.get().identity().get(); + pathName = new File( fileConfiguration.dataDirectory(), storeId ).getAbsolutePath(); } else { pathName = System.getProperty( "user.dir" ) + "/qi4j/filestore/"; } } - File rootDirectory = new File( pathName ).getAbsoluteFile(); - dataDirectory = new File( rootDirectory, "data" ); + dataDirectory = new File( pathName ).getAbsoluteFile(); if( !dataDirectory.exists() ) { if( !dataDirectory.mkdirs() ) @@ -219,7 +217,7 @@ public class FileEntityStoreMixin File dataFile = getDataFile( ref ); if( dataFile.exists() ) { - throw new EntityAlreadyExistsException(ref); + throw new EntityAlreadyExistsException( ref ); } store( dataFile, stateArray ); } @@ -253,6 +251,7 @@ public class FileEntityStoreMixin { throw new EntityNotFoundException( ref ); } + //noinspection ResultOfMethodCallIgnored dataFile.delete(); } } ); @@ -261,7 +260,7 @@ public class FileEntityStoreMixin { if( e instanceof EntityStoreException ) { - throw (EntityStoreException) e; + throw e; } else { @@ -282,8 +281,8 @@ public class FileEntityStoreMixin output.receiveFrom( new Sender() { @Override - public void sendTo( Receiver receiver ) - throws ReceiverThrowableType, IOException + public void sendTo( Receiver receiver ) + throws ThrowableType, IOException { for( File sliceDirectory : dataDirectory.listFiles() ) { @@ -336,8 +335,8 @@ public class FileEntityStoreMixin output.receiveFrom( new Sender() { @Override - public void sendTo( Receiver receiver ) - throws ReceiverThrowableType, IOException + public void sendTo( Receiver receiver ) + throws ThrowableType, IOException { for( File sliceDirectory : dataDirectory.listFiles() ) { @@ -355,15 +354,57 @@ public class FileEntityStoreMixin private File getDataFile( String identity ) { + identity = replaceInvalidChars( identity ); String slice = "" + ( Math.abs( identity.hashCode() ) % slices ); File sliceDirectory = new File( dataDirectory, slice ); if( !sliceDirectory.exists() ) { + //noinspection ResultOfMethodCallIgnored sliceDirectory.mkdirs(); } return new File( sliceDirectory, identity + ".json" ); } + /** + * We need to replace all characters that some file system can't handle. + *

+ * The resulting files should be portable across filesystems. + *

+ * + * @param identity The identity that needs a file to be stored in. + * + * @return A filesystem-safe name. + */ + private String replaceInvalidChars( String identity ) + { + StringBuilder b = new StringBuilder( identity.length() + 30 ); + for( int i = 0; i < identity.length(); i++ ) + { + char ch = identity.charAt( i ); + if( ( ch >= 'a' && ch <= 'z' ) + || ( ch >= 'A' && ch <= 'Z' ) + || ( ch >= '0' && ch <= '9' ) + || ch == '_' || ch == '.' || ch == '-' ) + { + b.append( ch ); + } + else + { + int value = (int) ch; + b.append( '~' ); + b.append( toHex( value ) ); + } + + } + return b.toString(); + } + + private String toHex( int value ) + { + String result = "000" + Integer.toHexString( value ); + return result.substring( result.length() - 4 ); + } + private File getDataFile( EntityReference ref ) { return getDataFile( ref.identity() ); @@ -372,7 +413,7 @@ public class FileEntityStoreMixin private byte[] fetch( File dataFile ) throws IOException { - byte[] buf = new byte[ 1000 ]; + byte[] buf = new byte[1000]; BufferedInputStream in = null; FileInputStream fis = null; try