[Yanel-dev] Many fixes for the Split Path Topic: Final Patch !
Balz Schreier
balz.schreier at gmail.com
Fri Oct 29 23:55:02 CEST 2010
Skipped content of type multipart/alternative-------------- next part -----=
---------
Index: src/impl/java/org/wyona/yarep/impl/repo/vfs/VirtualFileSystemNode.ja=
va
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- src/impl/java/org/wyona/yarep/impl/repo/vfs/VirtualFileSystemNode.java =
(revision 54229)
+++ src/impl/java/org/wyona/yarep/impl/repo/vfs/VirtualFileSystemNode.java =
(working copy)
@@ -11,23 +11,17 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.List;
=
+import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.Field.Index;
-import org.apache.lucene.document.Field.Store;
-import org.apache.lucene.index.IndexWriter;
-
import org.wyona.yarep.core.NoSuchRevisionException;
import org.wyona.yarep.core.Node;
import org.wyona.yarep.core.NodeStateException;
@@ -39,6 +33,7 @@
import org.wyona.yarep.core.Revision;
import org.wyona.yarep.core.UID;
import org.wyona.yarep.core.attributes.VersionableV1;
+import org.wyona.yarep.core.impl.vfs.SplitPathConfig;
import org.wyona.yarep.impl.AbstractNode;
import org.wyona.yarep.impl.DefaultProperty;
=
@@ -99,10 +94,15 @@
protected void init() throws RepositoryException {
=
this.contentDir =3D getRepository().getContentDir();
- this.contentFile =3D new File(this.contentDir, getRepository().spl=
itPath(this.uuid));
+ if (getRepository().getSplitPathConfig() =3D=3D null) {
+ throw new RepositoryException("Repository does not have a spli=
t path config instance! Make sure that Repository.init() is called before y=
ou use it!");
+ }
+ String maybeSplitPath =3D SplitPathConfig.splitPathIfRequired(this=
.uuid, getRepository().getSplitPathConfig());
+ this.contentFile =3D new File(this.contentDir, maybeSplitPath);
+ log.debug("New Node gets created: "+contentFile.getAbsolutePath());
this.backupContentFile =3D new File(this.contentDir, this.uuid);
=
- String metauuid =3D getRepository().splitPath(uuid + META_DIR_SUFF=
IX);
+ String metauuid =3D SplitPathConfig.splitPathIfRequired(uuid + MET=
A_DIR_SUFFIX, getRepository().getSplitPathConfig());
if (getRepository().getMetaDir() !=3D null) {
this.metaDir =3D new File(getRepository().getMetaDir(), metauu=
id);
this.backupMetaDir =3D new File(getRepository().getMetaDir(), =
uuid + META_DIR_SUFFIX);
@@ -242,10 +242,81 @@
public Node[] getNodes() throws RepositoryException {
Path[] childPaths;
if (getRepository().isSplitPathEnabled()) {
- // TODO: Unsplit paths
- log.warn("TODO: Unsplit paths...");
- childPaths =3D getRepository().getMap().getChildren(new Path(t=
his.path));
+ =
+ File startingDirectory =3D new File(contentDir + path);
+ log.warn("startingDirectory=3D "+startingDirectory);
+ if (!startingDirectory.exists()) {
+ log.warn("No such file or directory: " + startingDirectory=
);
+ childPaths =3D new Path[0];
+ }
+ if (startingDirectory.isFile()) {
+ log.warn("Can not get children form a file! : " + starting=
Directory);
+ childPaths =3D new Path[0];
+ }
+ =
+ // only if the current path belongs to a "include" path for th=
e split paths, we search ALL children, otherwise just the direct children
+ log.warn("Checking whether this path is include: "+path);
+ if (!SplitPathConfig.isIncludePath(path, getRepository().getSp=
litPathConfig())) {
+ childPaths =3D getRepository().getMap().getChildren(new Pa=
th(path));
+ =
+ } else {
+ List<File> allChildren =3D getAllFiles(startingDirectory);=
// get all children from the location "this.path"
+ log.debug("Number of children: " + allChildren.size() + " =
(" + startingDirectory + ")");
+ List<Path> validChildrenPaths =3D new ArrayList<Path>();
+ String fileSepForRegEx =3D File.separator;
+ if (fileSepForRegEx.equals("\\")) {
+ fileSepForRegEx =3D "\\\\"; // this is a double backsl=
ash, used for the regex later
+ }
+ =
+ for (File child: allChildren) {
+ String childFullPath =3D child.getAbsolutePath().repla=
ceAll(fileSepForRegEx, "/"); // whatever the file separator was, yarep uses=
"/"
+ log.debug("startingDirectory=3D "+startingDirectory);
+ log.debug("child =3D "+child.getAbsolutePath());
+ if (childFullPath.startsWith(contentDir.getAbsolutePat=
h())) {
+ String pathAndNode =3D childFullPath.substring(con=
tentDir.getAbsolutePath().length()); // =3D starts with this.path, e.g. "/p=
ath/node"
+ log.debug("1. pathAndNode =3D "+pathAndNode);
+ String unsplitPathAndNode =3D SplitPathConfig.unsp=
litPathIfRequired(pathAndNode, getRepository().getSplitPathConfig());
+ String unsplitNode =3D unsplitPathAndNode.substrin=
g(path.length()); // we remove the path (prefix) from e.g. "/path/node.xml"=
-> "/node.xml"
+ log.debug("2. unsplitNode =3D "+unsplitNode);
+ boolean ignore =3D ((org.wyona.yarep.impl.VFileSys=
temMapImpl) getRepository().getMap()).ignorePath(unsplitNode);
+ if (!ignore) {
+ String newPath =3D null;
+ if (path.equals(File.separator)) {
+ newPath =3D unsplitNode;
+ if (!newPath.startsWith("/")) {
+ newPath =3D "/" + newPath;
+ }
+ log.debug("path was File separator. newPat=
h =3D "+newPath);
+ =
+ } else if (path.toString().endsWith(File.separ=
ator) || path.toString().endsWith("/")) {
+ newPath =3D path.substring(0,path.length()=
-1);
+ if (!unsplitNode.startsWith("/")) {
+ unsplitNode =3D "/" + unsplitNode;
+ }
+ newPath =3D path + unsplitNode;
+ log.debug("path ended with a /. newPath =
=3D "+newPath.toString());
+ } else {
+ // NOTE: Do not use File.separator here, b=
ecause it's the repository path and not the Operating System's File System =
path
+ if (!unsplitNode.startsWith("/")) {
+ unsplitNode =3D "/" + unsplitNode;
+ }
+ newPath =3D path + unsplitNode;
+ log.debug("path does not end with a /. new=
Path =3D "+newPath.toString());
+ }
+ validChildrenPaths.add(new Path(newPath));
+ log.warn("getNodes('"+path+"'): ADDED: "+unspl=
itNode);
+ } else {
+ log.warn("getNodes('"+path+"'): IGNORED: "+unsp=
litNode);
+ }
+ } else {
+ log.error("Something is wrong: children are not wi=
thin parents!");
+ }
+ }
+ childPaths =3D validChildrenPaths.toArray(new Path[validCh=
ildrenPaths.size()]); =
+ } // end if-else: include or not
+
} else {
+ // split path is not enabled
childPaths =3D getRepository().getMap().getChildren(new Path(t=
his.path));
}
=
@@ -255,8 +326,30 @@
}
return childNodes;
}
- =
+
/**
+ * =
+ * @param dir
+ * @return List of Files (directories are NOT in the list!)
+ */
+ private List<File> getAllFiles(File dir) {
+ List<File> result =3D new ArrayList<File>();
+ if (dir.isDirectory()) {
+ File[] filesAndDirsArray =3D dir.listFiles();
+ List<File> filesAndDirs =3D Arrays.asList(filesAndDirsArray);
+ for (File file : filesAndDirs) {
+ if (file.isFile()) {
+ result.add(file);
+ } else {
+ List<File> deeperList =3D getAllFiles(file);
+ result.addAll(deeperList);
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
* @see org.wyona.yarep.core.Node#addNode(java.lang.String, int)
*/
public Node addNode(String name, int type) throws RepositoryException {
@@ -264,11 +357,16 @@
if (getPath().endsWith("/")) {
newPath =3D getPath() + name;
}
+ // in case the new node referenced by "name" is added to ROOT ("/"=
) we have to delete a potential / at the beginning:
+ if (newPath.startsWith("//")) {
+ newPath =3D newPath.substring(1);
+ }
log.debug("adding node: " + newPath);
if (this.repository.existsNode(newPath)) {
throw new RepositoryException("Node exists already: " + newPat=
h);
}
- UID uid =3D getRepository().getMap().create(new Path(getRepository=
().splitPath(newPath)), type);
+ String maybeSplitPath =3D SplitPathConfig.splitPathIfRequired(newP=
ath, getRepository().getSplitPathConfig());
+ UID uid =3D getRepository().getMap().create(new Path(maybeSplitPat=
h), type);
// create file:
File file =3D new File(this.contentDir, uid.toString());
try {
Index: src/impl/java/org/wyona/yarep/impl/repo/vfs/VirtualFileSystemReposit=
ory.java
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- src/impl/java/org/wyona/yarep/impl/repo/vfs/VirtualFileSystemRepository=
.java (revision 54229)
+++ src/impl/java/org/wyona/yarep/impl/repo/vfs/VirtualFileSystemRepository=
.java (working copy)
@@ -14,9 +14,6 @@
import org.apache.avalon.framework.configuration.DefaultConfigurationBuild=
er;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.index.IndexWriter;
-
import org.wyona.commons.io.FileUtil;
import org.wyona.yarep.core.Map;
import org.wyona.yarep.core.NoSuchNodeException;
@@ -27,6 +24,7 @@
import org.wyona.yarep.core.Revision;
import org.wyona.yarep.core.Storage;
import org.wyona.yarep.core.UID;
+import org.wyona.yarep.core.impl.vfs.SplitPathConfig;
import org.wyona.yarep.core.search.Indexer;
import org.wyona.yarep.core.search.SearchException;
import org.wyona.yarep.core.search.Searcher;
@@ -115,11 +113,7 @@
=
// Configuration parameters of the <splitpath ...> element
private boolean splitPathEnabled =3D false;
- private int splitparts =3D 0;
- private int splitlength =3D 0;
- private String DEFAULT_DUMMY_SEPARATOR_VALUE =3D "-";
- private String dummySeparator =3D DEFAULT_DUMMY_SEPARATOR_VALUE;
- private String[] includepaths =3D {};
+ private SplitPathConfig splitPathConfig =3D new SplitPathConfig();
=
/**
*
@@ -136,7 +130,7 @@
}
=
/**
- * Read respectively load repository configuration
+ * Load repository configuration
*/
public void readConfiguration(File configFile) throws RepositoryExcept=
ion {
this.configFile =3D configFile;
@@ -213,23 +207,22 @@
Configuration splitConfig =3D config.getChild("splitpath", fal=
se);
if (splitConfig !=3D null) {
splitPathEnabled =3D true;
- String depth =3D splitConfig.getAttribute("depth", "0");
- splitparts =3D Integer.parseInt(depth);
+ splitPathConfig.setSplitparts(Integer.parseInt(splitConfig=
.getAttribute("depth", "0")));
+ splitPathConfig.setSplitlength(Integer.parseInt(splitConfi=
g.getAttribute("length", "0")));
=
- String length;
- length =3D splitConfig.getAttribute("length", "0");
- splitlength =3D Integer.parseInt(length);
-
- dummySeparator =3D splitConfig.getAttribute("escape", DEFA=
ULT_DUMMY_SEPARATOR_VALUE);
-
- int c =3D splitConfig.getChildren("include").length;
- int i =3D 0;
- if (c > 0) {
- includepaths =3D new String[c];
+ int numberOfIncludePaths =3D splitConfig.getChildren("incl=
ude").length;
+ if (numberOfIncludePaths > 0) {
+ String[] includepaths =3D new String[numberOfIncludePa=
ths];
+ int i =3D 0;
for (Configuration include : splitConfig.getChildren("=
include")) {
includepaths[i++] =3D include.getAttribute("path");
}
+ splitPathConfig.setIncludepaths(includepaths);
}
+ // NOTE: This repository uses the VFileSystemMapImpl: But =
we do not tell the map about the splitting.
+ // Splitting is known to this repository and the nod=
e only.
+ // ((org.wyona.yarep.impl.VFileSystemMapImpl) map).setSpli=
tPathConfig(splitPathConfig);
+ // ((org.wyona.yarep.impl.VFileSystemMapImpl) map).setSpli=
tPathEnabled(true);
} =
} catch (Exception e) {
log.error(e.toString());
@@ -291,12 +284,7 @@
return delete(path);
}
=
-
- /**
- * @see org.wyona.yarep.core.Repository#exists(org.wyona.yarep.core.Pa=
th)
- */
public boolean exists(Path path) throws RepositoryException {
- log.warn("DEPRECATED");
return existsNode(path.toString());
}
=
@@ -401,7 +389,8 @@
path =3D path.substring(0, path.length() - 1);
}
if (splitPathEnabled) {
- return map.exists(new Path(splitPath(path))) || map.exists(new=
Path(path)); // INFO: The OR is because of backwards compatibility in case=
that a node exists with an unsplitted path, because it has not been migrat=
ed yet (which can happen if it has only been read so far, but never written=
since introducing the split path configuration)
+ String maybeSplit =3D SplitPathConfig.splitPathIfRequired(path=
, splitPathConfig);
+ return map.exists(new Path(maybeSplit)) || map.exists(new Path=
(path));
} else {
return map.exists(new Path(path));
}
@@ -416,7 +405,8 @@
path =3D path.substring(0, path.length() - 1);
}
=
- if ((splitPathEnabled && map.exists(new Path(splitPath(path)))) ||=
map.exists(new Path(path))) {
+ String maybeSplit =3D SplitPathConfig.splitPathIfRequired(path, sp=
litPathConfig);
+ if ((splitPathEnabled && map.exists(new Path(maybeSplit))) || map.=
exists(new Path(path))) {
String uuid =3D new UID(path).toString();
return new VirtualFileSystemNode(this, path, uuid);
} else {
@@ -609,98 +599,20 @@
return true;
}
=
- /**
- * Splits a String such that the result can be used as a repo path for=
a tree-like repo structure.
- *
- * This method splits off n strings (where n =3D parts) of length part=
length, e.g. if
- * splitPath("ec2c0c02-1d7d-4a21-8a39-68f9f72dea09", 3, 4) is called, =
then:
- * in: ec2c0c02-1d7d-4a21-8a39-68f9f72dea09, 3, 4
- * out: ec2c/0c02/-1d7/d-4a21-8a39-68f9f72dea09
- *
- * If the strings length is shorter than parts * partslength, then as =
many
- * parts as possible are split, e.g.
- * in: foobar, 2, 5
- * out: fooba/r
- * in: lorem, 3, 10
- * out: lorem
- *
- * An example with "/" characters:
- * in: /foobar/lorem/ipsum.txt, parts =3D 3, lenght =3D 3
- * out: /foo/bar/-lo/rem/ipsum.txt
- *
- * @param uuid
- * @return split uuid
- */
- String splitPath(String path) {
- // NOTE: uuid should be a full yarep path, so we can safely remove
- // the leading slash
- =
- // check if the given path matches any of the include values
- // in the configuration
- boolean include =3D false;
- String base =3D "";
- for (String s : includepaths) {
- if (path.startsWith(s)) {
- include =3D true;
- base =3D s;
- break;
- }
- }
+ public SplitPathConfig getSplitPathConfig() {
+ return splitPathConfig;
+ }
=
- // return the path unchanged if it doesn't match
- // any of the include values
- if (!include) {
- return path;
- }
- =
- // remove the leading base string, will be added again later
- path =3D path.substring(base.length(), path.length());
-
- // replace "/" characters where needed
- if (path.length() <=3D splitparts * splitlength) {
- path =3D path.replaceAll("/", dummySeparator);
- } else {
- path =3D String.format("%s%s",
- path.substring(0, splitparts * splitlength).replaceAll=
("/", dummySeparator),
- path.substring(splitparts * splitlength));
- }
-
- // now do the actual splitting
- int len =3D path.length();
- int pos =3D 0;
- String out =3D "";
-
- int partc =3D 0;
- int w;
- while (len > 0 && partc < splitparts) {
- partc++;
- if (len < splitlength) {
- w =3D len;
- } else {
- w =3D splitlength;
- }
- out +=3D path.substring(pos, pos + w);
- pos +=3D w;
- len -=3D w;
-
- if (len > 0) {
- out +=3D "/";
- }
- }
-
- // append remainder
- if (len > 0) {
- out +=3D path.substring(pos, pos + len);
- }
-
- // finally, add the leading zero again and return the new path
- return base + out;
+ public void setSplitPathConfig(SplitPathConfig splitPathConfig) {
+ this.splitPathConfig =3D splitPathConfig;
}
=
- /**
- * Check whether split path is enabled and make this available to clas=
ses within this package
- */
- boolean isSplitPathEnabled() {
+ public boolean isSplitPathEnabled() {
return splitPathEnabled;
}
+
+ public void setSplitPathEnabled(boolean splitPathEnabled) {
+ this.splitPathEnabled =3D splitPathEnabled;
+ }
+
}
Index: src/impl/java/org/wyona/yarep/impl/VFileSystemMapImpl.java
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- src/impl/java/org/wyona/yarep/impl/VFileSystemMapImpl.java (revision 54=
229)
+++ src/impl/java/org/wyona/yarep/impl/VFileSystemMapImpl.java (working cop=
y)
@@ -1,23 +1,22 @@
package org.wyona.yarep.impl;
=
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.apache.avalon.framework.configuration.Configuration;
-
+import org.apache.log4j.Category;
import org.wyona.commons.io.FileUtil;
import org.wyona.yarep.core.Map;
import org.wyona.yarep.core.Path;
import org.wyona.yarep.core.RepositoryException;
import org.wyona.yarep.core.UID;
+import org.wyona.yarep.core.impl.vfs.SplitPathConfig;
=
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.BufferedReader;
-import java.io.FilenameFilter;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.log4j.Category;
-
/**
*
*/
@@ -29,7 +28,11 @@
protected Pattern[] ignorePatterns;
protected ChildrenFilter childrenFilter =3D new ChildrenFilter();
=
+ // Configuration parameters of the <splitpath ...> element
+ private boolean splitPathEnabled =3D false;
+ private SplitPathConfig splitPathConfig =3D new SplitPathConfig();
=
+
/**
*
*/
@@ -41,6 +44,27 @@
Configuration[] ignoreElements =3D mapConfig.getChildren("=
ignore");
setIgnorePatterns(ignoreElements);
}
+ // Read the <splitpath> configuration
+ log.debug("Reading Split Path Configuation");
+ Configuration splitConfig =3D mapConfig.getChild("splitpath", =
false);
+ if (splitConfig !=3D null) {
+ splitPathConfig.setSplitparts(Integer.parseInt(splitConfig=
.getAttribute("depth", "0")));
+ splitPathConfig.setSplitlength(Integer.parseInt(splitConfi=
g.getAttribute("length", "0")));
+ splitPathConfig.setEscapeChar(splitConfig.getAttribute("es=
cape", "-"));
+
+ int numberOfIncludePaths =3D splitConfig.getChildren("incl=
ude").length;
+ int i =3D 0;
+ if (numberOfIncludePaths > 0) {
+ String[] includepaths =3D new String[numberOfIncludePa=
ths];
+ for (Configuration include : splitConfig.getChildren("=
include")) {
+ includepaths[i++] =3D include.getAttribute("path");
+ }
+ splitPathConfig.setIncludepaths(includepaths);
+ }
+ log.debug("Split Path Configuration DONE");
+ splitPathEnabled =3D true;
+ } =
+ =
} catch(Exception e) {
log.error(e);
throw new RepositoryException("Could not read map configuratio=
n: " =
@@ -66,15 +90,14 @@
=
/**
* Test if path should be ignored
+ * @return true returns true if the path can be ignored
*/
- protected boolean ignorePath(String path) {
+ public boolean ignorePath(String path) {
if (ignorePatterns !=3D null) {
for (int i=3D0; i<this.ignorePatterns.length; i++) {
Matcher matcher =3D this.ignorePatterns[i].matcher(path); =
if (matcher.matches()) {
- if (log.isDebugEnabled()) {
- log.debug(path + " matched ignore pattern " + igno=
rePatterns[i].pattern());
- }
+ log.debug(path + " matched ignore pattern " + ignorePa=
tterns[i].pattern());
return true;
}
}
@@ -89,7 +112,14 @@
*
*/
public boolean isResource(Path path) throws RepositoryException {
- File file =3D new File(pathsDir + path.toString());
+ File file =3D null;
+ if (splitPathEnabled) {
+ String maybeSplitedPath =3D SplitPathConfig.splitPathIfRequire=
d(path.toString(), this.splitPathConfig);
+ file =3D new File(pathsDir + maybeSplitedPath);
+ }
+ if (file =3D=3D null || !file.exists()) {
+ file =3D new File(pathsDir + path.toString());
+ }
return file.isFile();
}
=
@@ -97,14 +127,21 @@
*
*/
public boolean exists(Path path) throws RepositoryException {
- File file =3D new File(pathsDir + path.toString());
- // TODO: Get name of repository for debugging ...
- //log.debug("File: " + file);
- return file.exists() && !ignorePath(file.getPath());
+ File file =3D null;
+ if (splitPathEnabled) {
+ String maybeSplitedPath =3D SplitPathConfig.splitPathIfRequire=
d(path.toString(), this.splitPathConfig);
+ file =3D new File(pathsDir + maybeSplitedPath);
+ }
+ if (file =3D=3D null || !file.exists()) {
+ file =3D new File(pathsDir + path.toString());
+ }
+ boolean result =3D file.exists() && !ignorePath(file.getPath());
+ log.debug("file.exists()=3D"+result+": File: "+file.getPath());
+ return result;
}
=
/**
- *
+ * Calling this method has no effect anymore because delete is done in=
the storage impl!
*/
public boolean delete(Path path) throws RepositoryException {
// don't do anything because if we delete the file here, the delete
@@ -118,41 +155,124 @@
*
*/
public boolean isCollection(Path path) throws RepositoryException {
- File file =3D new File(pathsDir + path.toString());
+ File file =3D null;
+ if (splitPathEnabled) {
+ String maybeSplitedPath =3D SplitPathConfig.splitPathIfRequire=
d(path.toString(), this.splitPathConfig);
+ file =3D new File(pathsDir + maybeSplitedPath);
+ }
+ if (file =3D=3D null || !file.exists()) {
+ file =3D new File(pathsDir + path.toString());
+ }
return file.isDirectory();
}
=
/**
- * Get children
+ * Get children, the path of the children includes the path of the par=
ent!
*/
public Path[] getChildren(Path path) throws RepositoryException {
- File file =3D new File(pathsDir + path.toString());
- if (!file.exists()) {
- log.warn("No such file or directory: " + file);
- return new Path[0];
- }
+ // Note: path is always NOT splited, because the caller of this me=
thod does not know anything about it
+ log.debug("path =3D "+path.toString());
+ if (splitPathEnabled) {
+ File startingDirectory =3D new File(pathsDir + path.toString()=
);
+ if (!startingDirectory.exists()) {
+ log.warn("No such file or directory: " + startingDirectory=
);
+ return new Path[0];
+ }
+ if (startingDirectory.isFile()) {
+ log.warn("Can not get children form a file! : " + starting=
Directory);
+ return new Path[0];
+ }
+ =
+ List<File> allChildren =3D getAllFiles(startingDirectory);
+ log.debug("Number of children: " + allChildren.size() + " (" +=
startingDirectory + ")");
+ List<Path> validChildrenPaths =3D new ArrayList<Path>();
+ String fileSepForRegEx =3D File.separator;
+ if (fileSepForRegEx.equals("\\")) {
+ fileSepForRegEx =3D "\\\\"; // this is a double backslash,=
used for the regex later
+ }
+ =
+ for (File child: allChildren) {
+ String unsplitPath =3D child.getAbsolutePath().replaceAll(=
fileSepForRegEx, "/"); // whatever the file separator was, yarep uses "/"
+ log.debug("startingDirectory=3D "+startingDirectory);
+ log.debug("child =3D "+child.getAbsolutePath());
+ if (unsplitPath.startsWith(startingDirectory.getAbsolutePa=
th())) {
+ unsplitPath =3D unsplitPath.substring(startingDirector=
y.getAbsolutePath().length());
+ log.debug("1. path to unsplit =3D "+unsplitPath);
+ unsplitPath =3D SplitPathConfig.unsplitPathIfRequired(=
unsplitPath, splitPathConfig);
+ log.debug("2. unsplitPath =3D "+unsplitPath);
+ Path newPath =3D null;
+ if (!ignorePath(unsplitPath)) {
+ if (path.toString().endsWith(File.separator)) {
+ newPath =3D new Path(path + unsplitPath);
+ log.debug("3a. Added "+newPath.toString());
+ } else {
+ // NOTE: Do not use File.separator here, becau=
se it's the repository path and not the Operating System's File System path
+ newPath =3D new Path(path + "/" + unsplitPath);
+ log.debug("3b. Added "+newPath.toString());
+ }
+ validChildrenPaths.add(newPath);
+ } else {
+ log.debug("ignored: "+child.getAbsolutePath());
+ }
+ } else {
+ log.error("Something is wrong: children are not within=
parents!");
+ }
+ }
+ Path[] childrenArray =3D validChildrenPaths.toArray(new Path[v=
alidChildrenPaths.size()]);
+ return childrenArray;
+ =
+ } else {
+ File file =3D new File(pathsDir + path.toString());
+ if (!file.exists()) {
+ log.warn("No such file or directory: " + file);
+ return new Path[0];
+ }
=
- String[] filenames =3D file.list(this.childrenFilter);
+ String[] filenames =3D file.list(this.childrenFilter);
=
- // NOTE: This situation should only occur if one is trying to get childre=
n for a file than a directory! One might want to consider to test first wit=
h isResource() or isCollection().
- if (filenames =3D=3D null) {
- log.warn("No children: " + path + " (" + file + ")");
- return new Path[0];
- }
+ // NOTE: This situation should only occur if one is trying to get =
children for a file than a directory! One might want to consider to test fi=
rst with isResource() or isCollection().
+ if (filenames =3D=3D null) {
+ log.warn("No children: " + path + " (" + file + ")");
+ return new Path[0];
+ }
=
- log.debug("Number of children: " + filenames.length + " (" + file =
+ ")");
- Path[] children =3D new Path[filenames.length];
- for (int i =3D 0;i < children.length; i++) {
- if (path.toString().endsWith(File.separator)) {
- children[i] =3D new Path(path + filenames[i]);
- } else {
- // NOTE: Do not use File.separator here, because it's the =
repository path and not the Operating System File System path
- children[i] =3D new Path(path + "/" + filenames[i]);
+ log.debug("Number of children: " + filenames.length + " (" + f=
ile + ")");
+ Path[] children =3D new Path[filenames.length];
+ for (int i =3D 0;i < children.length; i++) {
+ if (path.toString().endsWith(File.separator)) {
+ children[i] =3D new Path(path + filenames[i]);
+ } else {
+ // NOTE: Do not use File.separator here, because it's =
the repository path and not the Operating System File System path
+ children[i] =3D new Path(path + "/" + filenames[i]);
+ }
+ log.debug("Child: " + children[i]);
}
- log.debug("Child: " + children[i]);
+ return children;
+ =
}
- return children;
}
+ =
+ /**
+ * =
+ * @param dir
+ * @return List of Files (directories are NOT in the list!)
+ */
+ private List<File> getAllFiles(File dir) {
+ List<File> result =3D new ArrayList<File>();
+ if (dir.isDirectory()) {
+ File[] filesAndDirsArray =3D dir.listFiles();
+ List<File> filesAndDirs =3D Arrays.asList(filesAndDirsArray);
+ for (File file : filesAndDirs) {
+ if (file.isFile()) {
+ result.add(file);
+ } else {
+ List<File> deeperList =3D getAllFiles(file);
+ result.addAll(deeperList);
+ }
+ }
+ }
+ return result;
+ }
=
/**
* Get UID
@@ -163,11 +283,14 @@
}
=
/**
- * Create UID
+ * Create UID:
*/
public synchronized UID create(Path path, int type) throws RepositoryE=
xception {
+ log.debug("pathsDir =3D "+pathsDir.getAbsolutePath());
+ log.debug("path =3D "+path);
+ log.debug("path parent =3D "+path.getParent());
// TODO: Check if leading slash should be removed ...
- File parent =3D new File(pathsDir + File.separator + path.getParen=
t().toString());
+ File parent =3D new File(pathsDir + File.separator + path.getParen=
t().toString()); // e.g. access-control/users
if (!parent.exists()) {
log.warn("Directory will be created: " + parent);
parent.mkdirs();
@@ -176,9 +299,35 @@
new File(parent, path.getName()).mkdir();
} else {
try {
- if(!new File(parent, path.getName()).createNewFile()) log.=
warn("File has not been created: " + new File(parent, path.getName()));
+ if (splitPathEnabled) {
+ // splitted e.g: ab/cd/4.xml
+ String maybeSplitedPath =3D SplitPathConfig.splitPathI=
fRequired(path.toString(), this.splitPathConfig);
+ log.debug("maybeSplited =3D "+maybeSplitedPath);
+ String newParent =3D pathsDir.getAbsolutePath();
+ if (maybeSplitedPath.contains("/")) {
+ // newparent for splitted above would be pathsDir/=
ab/cd
+ newParent =3D newParent + maybeSplitedPath.substri=
ng(0,maybeSplitedPath.lastIndexOf("/")+1);
+ }
+ String newFileName =3D new File(maybeSplitedPath).getN=
ame();
+ log.debug("new parent =3D "+newParent);
+ log.debug("new file name =3D "+newFileName);
+ File newFilePath =3D new File(newParent , newFileName);
+ new File(newParent).mkdirs();
+ log.debug("new parent exists: "+new File(newParent).ex=
ists());
+ boolean created =3D newFilePath.createNewFile();
+ log.debug("new file exists: "+newFilePath.exists());
+ log.debug("new file is directory: "+newFilePath.isDire=
ctory());
+ if (!created) {
+ log.debug("Maybe file has not been created: " + ne=
wFilePath.getAbsolutePath()); // On Mac OSX 10.6, the file gets created eve=
n in this case
+ }
+ =
+ } else {
+ if(!new File(parent, path.getName()).createNewFile()) =
log.debug("File has not been created: " + new File(parent, path.getName()));
+ }
+
+ =
} catch (Exception e) {
- log.error(e.getMessage(), e);
+ log.error("Could not create new file!! Exception: "+e.getM=
essage(), e);
}
}
=
@@ -186,7 +335,7 @@
}
=
/**
- *
+ * An exception gets thrown if you call this method because symbolic l=
inks are not implemented for virtual file systems!
*/
public void addSymbolicLink(Path path, UID uid) throws RepositoryExcep=
tion {
throw new RepositoryException("Symbolic links not implemented for =
virtual file system!");
@@ -199,6 +348,9 @@
public ChildrenFilter() {
}
=
+ /**
+ * @param dir is ignored in this implementation
+ */
public boolean accept(File dir, String name) {
=
if (VFileSystemMapImpl.this.ignorePath(name)) {
@@ -224,4 +376,20 @@
ignorePatterns =3D null; // see ignorePath(String)
}
}
+
+ public SplitPathConfig getSplitPathConfig() {
+ return splitPathConfig;
+ }
+
+ public void setSplitPathConfig(SplitPathConfig splitPathConfig) {
+ this.splitPathConfig =3D splitPathConfig;
+ }
+
+ public boolean isSplitPathEnabled() {
+ return splitPathEnabled;
+ }
+
+ public void setSplitPathEnabled(boolean splitPathEnabled) {
+ this.splitPathEnabled =3D splitPathEnabled;
+ }
}
Index: src/impl/java/org/wyona/yarep/core/impl/vfs/VFileSystemStorage.java
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- src/impl/java/org/wyona/yarep/core/impl/vfs/VFileSystemStorage.java (re=
vision 54229)
+++ src/impl/java/org/wyona/yarep/core/impl/vfs/VFileSystemStorage.java (wo=
rking copy)
@@ -1,12 +1,5 @@
package org.wyona.yarep.core.impl.vfs;
=
-import org.wyona.commons.io.FileUtil;
-import org.wyona.yarep.core.NoSuchNodeException;
-import org.wyona.yarep.core.Path;
-import org.wyona.yarep.core.RepositoryException;
-import org.wyona.yarep.core.Storage;
-import org.wyona.yarep.core.UID;
-
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
@@ -15,6 +8,12 @@
=
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.log4j.Category;
+import org.wyona.commons.io.FileUtil;
+import org.wyona.yarep.core.NoSuchNodeException;
+import org.wyona.yarep.core.Path;
+import org.wyona.yarep.core.RepositoryException;
+import org.wyona.yarep.core.Storage;
+import org.wyona.yarep.core.UID;
=
/**
*
@@ -27,6 +26,12 @@
private String alternative =3D null;
private String dirListingMimeType =3D "application/xml";
=
+ // Configuration parameters of the <splitpath ...> element
+ private SplitPathConfig splitPathConfig =3D new SplitPathConfig();
+ private boolean splitPathEnabled =3D false;
+ =
+ =
+
/**
* Read VFS Storage configuration
*/
@@ -50,6 +55,28 @@
dirListingMimeType =3D directoryConfig.getAttribute("mime-=
type", "application/xml");
log.debug("Mime type of directory listing: " + dirListingM=
imeType);
}
+
+ // Read the <splitpath> configuration
+ log.debug("Reading Split Path Configuation");
+ Configuration splitConfig =3D storageConfig.getChild("splitpat=
h", false);
+ if (splitConfig !=3D null) {
+ splitPathEnabled =3D true;
+ splitPathConfig.setSplitparts(Integer.parseInt(splitConfig=
.getAttribute("depth", "0")));
+ splitPathConfig.setSplitlength(Integer.parseInt(splitConfi=
g.getAttribute("length", "0")));
+ splitPathConfig.setEscapeChar(splitConfig.getAttribute("es=
cape", "-"));
+
+ int numberOfIncludePaths =3D splitConfig.getChildren("incl=
ude").length;
+ int i =3D 0;
+ if (numberOfIncludePaths > 0) {
+ String[] includepaths =3D new String[numberOfIncludePa=
ths];
+ for (Configuration include : splitConfig.getChildren("=
include")) {
+ includepaths[i++] =3D include.getAttribute("path");
+ }
+ splitPathConfig.setIncludepaths(includepaths);
+ }
+ log.debug("Split Path Configuration DONE");
+ } =
+ =
} catch (Exception e) {
log.error(e);
throw new RepositoryException(e.getMessage(), e);
@@ -60,57 +87,117 @@
*
*/
public Writer getWriter(UID uid, Path path) {
- return new VFileSystemRepositoryWriter(uid, path, contentDir);
+ // TODO We pass null as uid argument because the class anyway does=
not need it at this moment. =
+ // If in future this class is going to process the uid argument to=
o, the splitpathConfig object can be passed to it
+ String maybeSplitedPath =3D SplitPathConfig.splitPathIfRequired(pa=
th.toString(), this.splitPathConfig);
+ Path newPath =3D new Path(maybeSplitedPath);
+ Writer writer =3D null;
+ try {
+ writer =3D new VFileSystemRepositoryWriter(null, newPath, cont=
entDir);
+ } catch (Exception e) {
+ }
+ if (writer =3D=3D null) {
+ writer =3D new VFileSystemRepositoryWriter(null, path, content=
Dir);
+ }
+ return writer;
}
=
/**
- *
+ * @param uid is ignored in this implementation!
*/
public OutputStream getOutputStream(UID uid, Path path) throws Reposit=
oryException {
- return new VFileSystemRepositoryOutputStream(uid, path, contentDir=
);
+ // TODO We pass null as uid argument because the class anyway does=
not need it at this moment. =
+ // If in future this class is going to process the uid argument to=
o, the splitpathConfig object can be passed to it
+ String maybeSplitedPath =3D SplitPathConfig.splitPathIfRequired(pa=
th.toString(), this.splitPathConfig);
+ Path newPath =3D new Path(maybeSplitedPath);
+ OutputStream out =3D null;
+ try {
+ out =3D new VFileSystemRepositoryOutputStream(null, newPath, c=
ontentDir);
+ } catch (Exception e) {
+ }
+ if (out =3D=3D null) {
+ out =3D new VFileSystemRepositoryOutputStream(null, path, cont=
entDir);
+ }
+ return out;
}
=
/**
*
*/
public Reader getReader(UID uid, Path path) throws NoSuchNodeException=
{
- return new VFileSystemRepositoryReader(uid, path, contentDir);
+ // TODO We pass null as uid argument because the class anyway does=
not need it at this moment. =
+ // If in future this class is going to process the uid argument to=
o, the splitpathConfig object can be passed to it
+ String maybeSplitedPath =3D SplitPathConfig.splitPathIfRequired(pa=
th.toString(), this.splitPathConfig);
+ Path newPath =3D new Path(maybeSplitedPath);
+ Reader reader =3D null;
+ try {
+ reader =3D new VFileSystemRepositoryReader(null, newPath, cont=
entDir);
+ } catch (Exception e) {
+ }
+ if (reader =3D=3D null) {
+ reader =3D new VFileSystemRepositoryReader(null, path, content=
Dir);
+ }
+ return reader;
}
=
/**
- *
+ * @param uid is ignored in this implementation!
*/
public InputStream getInputStream(UID uid, Path path) throws Repositor=
yException {
- return new VFileSystemRepositoryInputStream(uid, path, contentDir,=
alternative, dirListingMimeType);
+ // TODO: if uid is processed by VFileSystemRepositoryInputStream, =
the splitPathConfig must be passed to it too. =
+ String maybeSplitedPath =3D SplitPathConfig.splitPathIfRequired(pa=
th.toString(), this.splitPathConfig);
+ Path newPath =3D new Path(maybeSplitedPath);
+ InputStream in =3D null;
+ try {
+ in =3D new VFileSystemRepositoryInputStream(null, newPath, con=
tentDir, alternative, dirListingMimeType);
+ } catch (Exception e) {
+ }
+ if (in =3D=3D null) {
+ in =3D new VFileSystemRepositoryInputStream(null, path, conten=
tDir, alternative, dirListingMimeType);
+ }
+ return in;
}
=
/**
- *
+ * @param path is currently ignored!!
*/
public long getLastModified(UID uid, Path path) throws RepositoryExcep=
tion {
- File file =3D new File(contentDir.getAbsolutePath() + File.separat=
or + uid.toString());
+ String maybeSplitedPath =3D SplitPathConfig.splitPathIfRequired(ui=
d.toString(), this.splitPathConfig);
+ File file =3D new File(contentDir.getAbsolutePath() + File.separat=
or + maybeSplitedPath);
+ if (!file.exists()) {
+ file =3D new File(contentDir.getAbsolutePath() + File.separato=
r + uid.toString());
+ }
return file.lastModified(); =
}
=
/**
+ * @param path is currently not used!
* @return Size of file in bytes
*/
public long getSize(UID uid, Path path) throws RepositoryException {
- File file =3D new File(contentDir.getAbsolutePath() + File.separator =
+ uid.toString());
- return file.length(); =
+ String maybeSplitedPath =3D SplitPathConfig.splitPathIfRequired(ui=
d.toString(), this.splitPathConfig);
+ File file =3D new File(contentDir.getAbsolutePath() + File.separat=
or + maybeSplitedPath);
+ if (!file.exists()) {
+ file =3D new File(contentDir.getAbsolutePath() + File.separato=
r + uid.toString());
+ }
+ return file.length(); =
}
=
/**
- *
+ * @param path is currently not used!
*/
public boolean delete(UID uid, Path path) throws RepositoryException {
- File file =3D new File(contentDir.getAbsolutePath() + File.separat=
or + uid.toString());
+ String maybeSplitedPath =3D SplitPathConfig.splitPathIfRequired(ui=
d.toString(), this.splitPathConfig);
+ File file =3D new File(contentDir.getAbsolutePath() + File.separat=
or + maybeSplitedPath.toString());
+ if (!file.exists()) {
+ file =3D new File(contentDir.getAbsolutePath() + File.separato=
r + uid.toString());
+ }
log.debug("Try to delete: " + file);
return file.delete();
}
=
/**
- * =
+ * Not implemented at this moment
*/
public String[] getRevisions(UID uid, Path path) throws RepositoryExce=
ption {
log.warn("Versioning not implemented yet");
@@ -118,16 +205,32 @@
}
=
/**
- *
+ * Checks the existence via uid first and then via path parameter
*/
public boolean exists(UID uid, Path path) {
+ boolean exists =3D false;
if (uid !=3D null) {
- return new File(contentDir.getAbsolutePath() + File.separator =
+ uid.toString()).exists();
+ if (splitPathEnabled) {
+ File normalFile =3D new File(contentDir.getAbsolutePath() =
+ File.separator + uid.toString());
+ File splitFile =3D new File(contentDir.getAbsolutePath() +=
File.separator + SplitPathConfig.splitPathIfRequired(uid.toString(), this.=
splitPathConfig));
+ exists =3D normalFile.exists() || splitFile.exists();
+ } else {
+ exists =3D new File(contentDir.getAbsolutePath() + File.se=
parator + uid.toString()).exists();
+ }
+
} else if (path !=3D null) {
log.warn("No UUID specified, hence check path: " + path + " (C=
ontent dir: " + contentDir + ")");
- return new File(contentDir.getAbsolutePath() + File.separator =
+ path.toString()).exists();
- } else {
- return false;
- }
+ if (splitPathEnabled) {
+ File normalFile =3D new File(contentDir.getAbsolutePath() =
+ File.separator + path.toString());
+ File splitFile =3D new File(contentDir.getAbsolutePath() +=
File.separator + SplitPathConfig.splitPathIfRequired(path.toString(), this=
.splitPathConfig));
+ exists =3D normalFile.exists() || splitFile.exists();
+ } else {
+ exists =3D new File(contentDir.getAbsolutePath() + File.se=
parator + path.toString()).exists();
+ }
+
+ } =
+ return exists;
}
+ =
+
}
More information about the Yanel-development
mailing list