exo-jcr SVN: r2297 - jcr/trunk/packaging/module/src/main/javascript.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2010-04-21 10:25:06 -0400 (Wed, 21 Apr 2010)
New Revision: 2297
Modified:
jcr/trunk/packaging/module/src/main/javascript/jcr.packaging.module.js
Log:
EXOJCR-685: Upgraded to JBC 3.2.3.GA
Modified: jcr/trunk/packaging/module/src/main/javascript/jcr.packaging.module.js
===================================================================
--- jcr/trunk/packaging/module/src/main/javascript/jcr.packaging.module.js 2010-04-21 14:24:34 UTC (rev 2296)
+++ jcr/trunk/packaging/module/src/main/javascript/jcr.packaging.module.js 2010-04-21 14:25:06 UTC (rev 2297)
@@ -24,7 +24,7 @@
addDependency(new Project("jgroups", "jgroups", "jar", "2.6.13.GA")).
addDependency(new Project("stax", "stax-api", "jar", "1.0")).
// addDependency(new Project("stax", "stax", "jar", "1.2.0")).
- addDependency(new Project("org.jboss.cache","jbosscache-core","jar","3.2.3.CR1")).
+ addDependency(new Project("org.jboss.cache","jbosscache-core","jar","3.2.3.GA")).
addDependency(new Project("jboss.jbossts","jbossjts","jar","4.6.1.GA")).
addDependency(new Project("jboss.jbossts","jbossts-common","jar","4.6.1.GA")).
addDependency(new Project("org.apache.ws.commons","ws-commons-util","jar","1.0.1")).
16 years, 2 months
exo-jcr SVN: r2296 - jcr/trunk.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2010-04-21 10:24:34 -0400 (Wed, 21 Apr 2010)
New Revision: 2296
Modified:
jcr/trunk/pom.xml
Log:
EXOJCR-685: Upgraded to JBC 3.2.3.GA
Modified: jcr/trunk/pom.xml
===================================================================
--- jcr/trunk/pom.xml 2010-04-21 14:08:50 UTC (rev 2295)
+++ jcr/trunk/pom.xml 2010-04-21 14:24:34 UTC (rev 2296)
@@ -349,7 +349,7 @@
<dependency>
<groupId>org.jboss.cache</groupId>
<artifactId>jbosscache-core</artifactId>
- <version>3.2.3.CR1</version>
+ <version>3.2.3.GA</version>
</dependency>
<dependency>
<groupId>jboss.jbossts</groupId>
16 years, 2 months
exo-jcr SVN: r2295 - kernel/trunk.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2010-04-21 10:08:50 -0400 (Wed, 21 Apr 2010)
New Revision: 2295
Modified:
kernel/trunk/pom.xml
Log:
EXOJCR-685: Upgraded to JBC 3.2.3.GA
Modified: kernel/trunk/pom.xml
===================================================================
--- kernel/trunk/pom.xml 2010-04-21 14:07:02 UTC (rev 2294)
+++ kernel/trunk/pom.xml 2010-04-21 14:08:50 UTC (rev 2295)
@@ -179,7 +179,7 @@
<dependency>
<groupId>org.jboss.cache</groupId>
<artifactId>jbosscache-core</artifactId>
- <version>3.2.3.CR1</version>
+ <version>3.2.3.GA</version>
</dependency>
<dependency>
<groupId>org.jibx</groupId>
16 years, 2 months
exo-jcr SVN: r2294 - kernel/trunk/exo.kernel.component.ext.cache.impl.jboss.v3/src/main/java/org/exoplatform/services/cache/impl/jboss.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2010-04-21 10:07:02 -0400 (Wed, 21 Apr 2010)
New Revision: 2294
Modified:
kernel/trunk/exo.kernel.component.ext.cache.impl.jboss.v3/src/main/java/org/exoplatform/services/cache/impl/jboss/AbstractExoCache.java
Log:
EXOJCR-672: Temporary fix has been removed since it is fixed in JBC
Modified: kernel/trunk/exo.kernel.component.ext.cache.impl.jboss.v3/src/main/java/org/exoplatform/services/cache/impl/jboss/AbstractExoCache.java
===================================================================
--- kernel/trunk/exo.kernel.component.ext.cache.impl.jboss.v3/src/main/java/org/exoplatform/services/cache/impl/jboss/AbstractExoCache.java 2010-04-21 14:05:54 UTC (rev 2293)
+++ kernel/trunk/exo.kernel.component.ext.cache.impl.jboss.v3/src/main/java/org/exoplatform/services/cache/impl/jboss/AbstractExoCache.java 2010-04-21 14:07:02 UTC (rev 2294)
@@ -43,7 +43,6 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
@@ -108,22 +107,10 @@
/**
* {@inheritDoc}
*/
- @SuppressWarnings("unchecked")
public void clearCache()
{
- Set<Fqn> internalFqns = cache.getInternalFqns();
- for (Object childName : cache.peek(Fqn.ROOT, false, false).getChildrenNames())
- {
- if (!internalFqns.contains(Fqn.fromElements(childName)))
- {
- cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
- cache.removeNode(Fqn.fromRelativeElements(Fqn.ROOT, childName));
- }
- }
- // The code above can be replaced with the code below once the bug JBCACHE-1577
- // will be fixed in JBC
-// cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
-// cache.removeNode(Fqn.ROOT);
+ cache.getInvocationContext().getOptionOverrides().setCacheModeLocal(true);
+ cache.removeNode(Fqn.ROOT);
onClearCache();
}
16 years, 2 months
exo-jcr SVN: r2293 - kernel/trunk/exo.kernel.component.ext.cache.impl.jboss.v3/src/main/java/org/exoplatform/services/cache/impl/jboss.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2010-04-21 10:05:54 -0400 (Wed, 21 Apr 2010)
New Revision: 2293
Modified:
kernel/trunk/exo.kernel.component.ext.cache.impl.jboss.v3/src/main/java/org/exoplatform/services/cache/impl/jboss/AbstractExoCache.java
Log:
EXOJCR-612: Temporary fix has been removed since it is fixed in JBC
Modified: kernel/trunk/exo.kernel.component.ext.cache.impl.jboss.v3/src/main/java/org/exoplatform/services/cache/impl/jboss/AbstractExoCache.java
===================================================================
--- kernel/trunk/exo.kernel.component.ext.cache.impl.jboss.v3/src/main/java/org/exoplatform/services/cache/impl/jboss/AbstractExoCache.java 2010-04-21 11:32:28 UTC (rev 2292)
+++ kernel/trunk/exo.kernel.component.ext.cache.impl.jboss.v3/src/main/java/org/exoplatform/services/cache/impl/jboss/AbstractExoCache.java 2010-04-21 14:05:54 UTC (rev 2293)
@@ -253,15 +253,7 @@
*/
protected V putOnly(K key, V value)
{
- try
- {
- return cache.put(getFqn(key), key, value);
- }
- catch (NullPointerException e)
- {
- // to fix temporary the bug JBCACHE-1572
- }
- return null;
+ return cache.put(getFqn(key), key, value);
}
/**
16 years, 2 months
exo-jcr SVN: r2292 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl: dataflow/persistent/jbosscache and 1 other directory.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2010-04-21 07:32:28 -0400 (Wed, 21 Apr 2010)
New Revision: 2292
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexChangesFilter.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
Log:
EXOJCR-687: getParameterTime used instead of getParameterInteger
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexChangesFilter.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexChangesFilter.java 2010-04-20 13:51:59 UTC (rev 2291)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexChangesFilter.java 2010-04-21 11:32:28 UTC (rev 2292)
@@ -90,8 +90,8 @@
// try to get pushState parameters, since they are set programmatically only
Boolean pushState = config.getParameterBoolean(QueryHandlerParams.PARAM_JBOSSCACHE_PUSHSTATE, false);
- Integer pushStateTimeOut =
- config.getParameterInteger(QueryHandlerParams.PARAM_JBOSSCACHE_PUSHSTATE_TIMEOUT, 10000);
+ Long pushStateTimeOut =
+ config.getParameterTime(QueryHandlerParams.PARAM_JBOSSCACHE_PUSHSTATE_TIMEOUT, 10000L);
singletonStoreProperties.setProperty("pushStateWhenCoordinator", pushState.toString());
singletonStoreProperties.setProperty("pushStateWhenCoordinatorTimeout", pushStateTimeOut.toString());
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-04-20 13:51:59 UTC (rev 2291)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/JBossCacheWorkspaceStorageCache.java 2010-04-21 11:32:28 UTC (rev 2292)
@@ -98,7 +98,7 @@
public static final String JBOSSCACHE_EXPIRATION = "jbosscache-expiration-time";
- public static final int JBOSSCACHE_EXPIRATION_DEFAULT = 900000; // 15 minutes
+ public static final long JBOSSCACHE_EXPIRATION_DEFAULT = 900000; // 15 minutes
public static final String ITEMS = "$ITEMS".intern();
@@ -307,7 +307,7 @@
// if expiration is used, set appropriate factory with with timeout set via configuration (or default one 15minutes)
this.cache =
new BufferedJBossCache(factory.createCache(wsConfig.getCache()), useExpiration,
- wsConfig.getCache().getParameterInteger(JBOSSCACHE_EXPIRATION, JBOSSCACHE_EXPIRATION_DEFAULT));
+ wsConfig.getCache().getParameterTime(JBOSSCACHE_EXPIRATION, JBOSSCACHE_EXPIRATION_DEFAULT));
this.itemsRoot = Fqn.fromElements(ITEMS);
this.childNodes = Fqn.fromElements(CHILD_NODES);
16 years, 2 months
exo-jcr SVN: r2291 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-04-20 09:51:59 -0400 (Tue, 20 Apr 2010)
New Revision: 2291
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java
Log:
EXOJCR-671: FileCleaner - LinkedHashSet changed to ConcurrentLinkedQueue
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java 2010-04-20 13:36:19 UTC (rev 2290)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/io/FileCleaner.java 2010-04-20 13:51:59 UTC (rev 2291)
@@ -23,8 +23,9 @@
import org.exoplatform.services.log.Log;
import java.io.File;
-import java.util.LinkedHashSet;
+import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
/**
* Created by The eXo Platform SAS.
@@ -40,7 +41,7 @@
protected static Log log = ExoLogger.getLogger("exo.jcr.component.core.FileCleaner");
- protected Set<File> files = new LinkedHashSet<File>();
+ protected final ConcurrentLinkedQueue<File> files = new ConcurrentLinkedQueue<File>();
public FileCleaner()
{
@@ -77,11 +78,11 @@
/**
* @param file
*/
- public synchronized void addFile(File file)
+ public void addFile(File file)
{
if (file.exists())
{
- files.add(file);
+ files.offer(file);
}
}
@@ -106,51 +107,47 @@
*/
protected void callPeriodically() throws Exception
{
- if (files != null && files.size() > 0)
+ File file = null;
+ Set<File> notRemovedFiles = new HashSet<File>();
+ while ((file = files.poll()) != null)
{
- Set<File> oldFiles = files;
- files = new LinkedHashSet<File>();
- for (File file : oldFiles)
+ if (file.exists())
{
- if (file.exists())
+ if (!file.delete())
{
- if (!file.delete())
- {
- files.add(file);
+ notRemovedFiles.add(file);
- if (log.isDebugEnabled())
- log.debug("Could not delete " + (file.isDirectory() ? "directory" : "file")
- + ". Will try next time: " + file.getAbsolutePath());
- }
- else if (log.isDebugEnabled())
- {
- log.debug((file.isDirectory() ? "Directory" : "File") + " deleted : " + file.getAbsolutePath());
- }
+ if (log.isDebugEnabled())
+ log.debug("Could not delete " + (file.isDirectory() ? "directory" : "file")
+ + ". Will try next time: " + file.getAbsolutePath());
}
+ else if (log.isDebugEnabled())
+ {
+ log.debug((file.isDirectory() ? "Directory" : "File") + " deleted : " + file.getAbsolutePath());
+ }
}
}
+
+ //add do lists tail all not removed files
+ if (!notRemovedFiles.isEmpty())
+ {
+ files.addAll(notRemovedFiles);
+ }
}
private void registerShutdownHook()
{
- // register shutdownhook for final cleaning up
+ // register shutdown hook for final cleaning up
try
{
Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
- Set<File> oldFiles = files;
- files = null;
- // synchronize on the list before iterating over it in order
- // to avoid ConcurrentModificationException (JCR-549)
- // @see java.lang.util.Collections.synchronizedList(java.util.List)
- synchronized (oldFiles)
+ File file = null;
+ while ((file = files.poll()) != null)
{
- for (File file : oldFiles)
- {
- file.delete();
- }
+ file.delete();
}
}
});
16 years, 3 months
exo-jcr SVN: r2290 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-04-20 09:36:19 -0400 (Tue, 20 Apr 2010)
New Revision: 2290
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java
Log:
EXOJCR-643: avoided redundant call to JBossCache on getUpdateInProgress()
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java 2010-04-20 13:30:10 UTC (rev 2289)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/jbosscache/JBossCacheIndexUpdateMonitor.java 2010-04-20 13:36:19 UTC (rev 2290)
@@ -108,6 +108,8 @@
{
// Currently READ_ONLY is set, so new lists should be fired to multiIndex.
cache.addCacheListener(this);
+ Object value = cache.get(parametersFqn, PARAMETER_NAME);
+ localUpdateInProgress = value != null ? (Boolean)value : false;
}
}
@@ -136,17 +138,7 @@
*/
public boolean getUpdateInProgress()
{
- if (IndexerIoMode.READ_ONLY == modeHandler.getMode())
- {
- Object value = cache.get(parametersFqn, PARAMETER_NAME);
- return value != null ? (Boolean)value : false;
- }
- else
- {
- // this node is read-write, so must read local value.
- // Local value is updated every time, but remote cache value is skipped is volatile changes are performed
- return localUpdateInProgress;
- }
+ return localUpdateInProgress;
}
/**
@@ -212,10 +204,11 @@
log.warn("The data cannot be found, we will try to get it from the cache");
value = cache.get(parametersFqn, PARAMETER_NAME);
}
- boolean updateInProgress = value != null ? (Boolean)value : false;
+ localUpdateInProgress = value != null ? (Boolean)value : false;
+
for (IndexUpdateMonitorListener listener : listeners)
{
- listener.onUpdateInProgressChange(updateInProgress);
+ listener.onUpdateInProgressChange(localUpdateInProgress);
}
}
}
16 years, 3 months
exo-jcr SVN: r2289 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2010-04-20 09:30:10 -0400 (Tue, 20 Apr 2010)
New Revision: 2289
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
Log:
EXOJCR-639: The method HasLocks has been added, The method getNumLocks should be launched as an Action Non Tx Aware and in getExactNodeOrCloseParentLock and getClosedChild, we check if the locks exist only once
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2010-04-16 14:19:43 UTC (rev 2288)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/lock/jbosscache/CacheableLockManagerImpl.java 2010-04-20 13:30:10 UTC (rev 2289)
@@ -443,14 +443,54 @@
return lockTimeOut;
}
+ private final LockActionNonTxAware<Integer, Object> getNumLocks = new LockActionNonTxAware<Integer, Object>()
+ {
+ public Integer execute(Object arg)
+ {
+ return ((CacheSPI<Serializable, Object>)cache).getNumberOfNodes() - 1;
+ }
+ };
+
@Managed
@ManagedDescription("The number of active locks")
public int getNumLocks()
{
- return ((CacheSPI<Serializable, Object>)cache).getNumberOfNodes() - 1;
+ try
+ {
+ return executeLockActionNonTxAware(getNumLocks, null);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return -1;
}
+ private final LockActionNonTxAware<Boolean, Object> hasLocks = new LockActionNonTxAware<Boolean, Object>()
+ {
+ public Boolean execute(Object arg)
+ {
+ return ((CacheSPI<Serializable, Object>)cache).getNode(lockRoot).hasChildrenDirect();
+ }
+ };
+
/**
+ * Indicates if some locks have already been created
+ */
+ private boolean hasLocks()
+ {
+ try
+ {
+ return executeLockActionNonTxAware(hasLocks, null);
+ }
+ catch (LockException e)
+ {
+ // ignore me will never occur
+ }
+ return true;
+ }
+
+ /**
* Return new instance of session lock manager.
*/
public SessionLockManager getSessionLockManager(String sessionId, SessionDataManager transientManager)
@@ -870,8 +910,13 @@
*/
public LockData getExactNodeOrCloseParentLock(NodeData node) throws RepositoryException
{
+ return getExactNodeOrCloseParentLock(node, true);
+ }
+
+ private LockData getExactNodeOrCloseParentLock(NodeData node, boolean checkHasLocks) throws RepositoryException
+ {
- if (node == null || getNumLocks() == 0)
+ if (node == null || (checkHasLocks && !hasLocks()))
{
return null;
}
@@ -882,7 +927,7 @@
NodeData parentData = (NodeData)dataManager.getItemData(node.getParentIdentifier());
if (parentData != null)
{
- retval = getExactNodeOrCloseParentLock(parentData);
+ retval = getExactNodeOrCloseParentLock(parentData, false);
}
}
return retval;
@@ -893,7 +938,7 @@
*/
public LockData getExactNodeLock(NodeData node) throws RepositoryException
{
- if (node == null || getNumLocks() == 0)
+ if (node == null || !hasLocks())
{
return null;
}
@@ -906,8 +951,13 @@
*/
public LockData getClosedChild(NodeData node) throws RepositoryException
{
+ return getClosedChild(node, true);
+ }
+
+ private LockData getClosedChild(NodeData node, boolean checkHasLocks) throws RepositoryException
+ {
- if (node == null || getNumLocks() == 0)
+ if (node == null || (checkHasLocks && !hasLocks()))
{
return null;
}
@@ -923,7 +973,7 @@
// child not found try to find dipper
for (NodeData nodeData : childData)
{
- retval = getClosedChild(nodeData);
+ retval = getClosedChild(nodeData, false);
if (retval != null)
return retval;
}
16 years, 3 months
exo-jcr SVN: r2288 - jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs.
by do-not-reply@jboss.org
Author: sergiykarpenko
Date: 2010-04-16 10:19:43 -0400 (Fri, 16 Apr 2010)
New Revision: 2288
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java
Log:
EXOJCR-664: Thread.wait() replaced with join()
Modified: jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java 2010-04-16 14:00:27 UTC (rev 2287)
+++ jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/impl/storage/value/fs/TestFileIOChannel.java 2010-04-16 14:19:43 UTC (rev 2288)
@@ -252,10 +252,11 @@
// channel.delete("testConcurrentReadFromIOChannel");
// should be enough to finish all the threads
- Thread.sleep(1000);
+ //Thread.sleep(1000);
for (int i = 0; i < 10; i++)
{
+ p[i].join();
assertEquals(100 * 100, p[i].getLen());
}
channel.delete("testConcurrentReadFromIOChannel");
@@ -282,14 +283,17 @@
channel.commit();
File f = new File(rootDir, "testDeleteLockedFileFromIOChannel0");
- new Probe(f).start();
+ Probe p = new Probe(f);
+ p.start();
+ p.join();
f = null;
- Thread.sleep(100);
+ // Thread.sleep(100);
// removed by FileCleaner
- Thread.sleep(3000);
+ //Thread.sleep(3000);
+
f = new File(rootDir, "testDeleteLockedFileFromIOChannel0");
// assertFalse(f.exists());
System.out.println(">>>>>>>>>>>>>" + f.canRead() + " " + f.exists() + " " + f.canWrite());
16 years, 3 months